1. Descripció del dataset

Aquest dataset prové de la pràctica anterior, en la qual, no vaig prestar gens d’atenció a la neteja de les dades, donant com a resultat un dataset molt brut. Això es va fer a proposit per tal de poder aprofitar aquest dataset en aquesta pràctica.

Aquest dataset conté informació sobre ofertes laborals trobades a la web proporcionada per l’estat Espanyol per a tal proposit.

La pregunta que volem respondre amb aquest dataset serà:

A la pràctica anterior enumerabem també les següents idees:

Però aquestes les deixarem per futurs treballs.

2. Integració i selecció de les dades d’interès a analitzar

Per aquest apartat ja es va crear un script python que s’encarregaba d’ajuntar les dades obtingudes en diferents dies. La idea darrera d’aquest script era la de recolectar totes les dades disponibles a la web en una primera pasada, i desprès anar actualitzant el dataset agafant dades diaries i agrupant-les sota el mateix fitxer .csv

Per tant, en aquest apartat considero que no haig de fer més que el ja fet fins a la data.

El script es pot trobar en la següent URL: [https://github.com/amilan/spanish_job_market/blob/master/src/dataset_merge.py]

També tinc en compte, que la web oficial de la qual es va extreure les dades, ja recopila aquestes dades de diferent fonts, així doncs, no considero que sigui necessari l’integració de dades de diferentes fonts, ja que aquesta ha estat realitzada anteriorment.

Hauria d’explicar una mica com faria aquesta integració en cas de que no hagués estat feta per la propia font utilitzada? Revisar si s’ha d’expandir més aquesta explicació sobre la integració i selecció de dades d’interès

En aquest apartat seleccionarem les dades necessaries per als nostres estudis. Hem de tenir en compte, que a la pràctica anterior hem vaig limitar a agafar totes les dades possibles i a possar-les en un fitxer .csv. Aquestes dades provenien d’una base de dades NoSQL, ja que vaig detectar que amb les mateixes crides, podiem obtenir dades amb diferents esquemes (schemaless). Així doncs, farem una selecció de les dades que utilitzarem i eliminarem així dades no necessàries o repetides.

Començem carregant les dades:

offers <- read.csv("./data/offers_dataset.csv")
head(offers)
length(offers$categoria)
[1] 40534

Com podem veure, tenim 40534 registres i 94 característiques, moltes de les quals no ens seràn d’utilitat.

names(offers)
 [1] "categoria"           "categoriaF"          "categoriaS"          "ciudad"             
 [5] "ciudadF"             "companiaSeleccion"   "competenciasReq"     "comunidad"          
 [9] "comunidadF"          "consulta1"           "consulta2"           "consulta3"          
[13] "consulta4"           "contenido"           "creador"             "cuestionario"       
[17] "discapacidad"        "duracion"            "educacion"           "educacionDes"       
[21] "educacionDesF"       "educacionF"          "educacionReq"        "educacionReqF"      
[25] "educacionS"          "email"               "empresaSocial"       "ett"                
[29] "fechaCreacion"       "fechaCreacionBoost"  "fechaCreacionPortal" "fechaIncorporacion" 
[33] "fechaRevision"       "formacionReq"        "horario"             "id"                 
[37] "jornada"             "jornadaF"            "localizacion"        "minExperiencia"     
[41] "nivel"               "noMeInteresa"        "numCandidatos"       "oReq"               
[45] "oferta"              "origen"              "pais"                "paisF"              
[49] "paisS"               "provincia"           "provinciaF"          "provinciaLimitrofe" 
[53] "provinciaS"          "publicado1"          "publicado2"          "publicado3"         
[57] "publicado4"          "respuesta1A"         "respuesta1B"         "respuesta2A"        
[61] "respuesta2B"         "respuesta2C"         "respuesta3A"         "respuesta3B"        
[65] "salarioMax"          "salarioMin"          "score"               "sector"             
[69] "sectorF"             "sisgarjuv"           "speState"            "speStateId"         
[73] "subcategoria"        "subcategoriaF"       "subcategoriaS"       "subsector"          
[77] "subsectorF"          "tamanoCompania2"     "telefono"            "tipoContrato"       
[81] "tipoContratoN"       "titulo"              "trabajosOfertados"   "url"                
[85] "valor1A"             "valor1B"             "valor2A"             "valor2B"            
[89] "valor3B"             "verMail"             "verSalarioMax"       "verSalarioMin"      
[93] "verTelefono"         "web"                

Així doncs, començarem seleccionant les dades d’interés. Recordem que la meva intenció es la de fer un estudi sobre els tipus d’ofertes de treballs a Espanya i en concret a cadascuna de les regions.

Primerament, comprovarem que només tenim dades d’ofertes realitzades a Espanya.

levels(offers$paisS)
[1] "CONGO"   "ESPAÑA" "ESPAÑA"  "ESPA��A"

Comprovem dues coses, que tenim ofertes d’Espanya i també al Congo, i que tenim un problema de codificació de caracters, ja que ens troba el país d’Espanya en tres factors diferents. Com que només volem utilitzar les dades de les ofertes a Espanya, podem seleccionar totes les que no siguin al Congo i desprès eliminar aquesta columna.

Podem corregir les dades erronees de país:

offers$paisS <- sub("ESPAÑA", "ESPAÑA", offers$paisS)
offers$paisS <- sub("ESPA��A", "ESPAÑA", offers$paisS)
levels(factor(offers$paisS))
[1] "CONGO"  "ESPAÑA"

També podriem haver canviat la codificació dels caracters, com veurem més endavant.

Seleccionem ara només les ofertes a Espanya.

#offers_sp <- subset(offers, !(paisS %in% c("CONGO"))
#offers_sp <- subset(offers, !(paisS == "CONGO"))
offers <- subset(offers, paisS == "ESPAÑA")
levels(factor(offers$paisS))
[1] "ESPAÑA"
# paisS es ara del tipus chr, hauriem de convertirla de nou a factor
offers$paisS <- factor(offers$paisS)
class(offers$paisS)
[1] "factor"

Seguidament, eliminarem les colummnes que ofereixen informació duplicada. Ens quedarem amb les característiques:

selected_features <- c("categoriaF", "ciudadF", "comunidadF", "educacionF", "fechaCreacion", "jornadaF", "paisS", "provinciaS", "salarioMax", "salarioMin", "subcategoriaS")
offers <- offers[selected_features]
head(offers)

3. Neteja de les dades

Les dades contenen zeros o elements buits? Com gestionaries aquests casos?

sapply(offers, function(x)(sum(is.na(x))))
   categoriaF       ciudadF    comunidadF    educacionF fechaCreacion      jornadaF         paisS 
            0             0             0             0             0             0             0 
   provinciaS    salarioMax    salarioMin subcategoriaS 
            0         38087         31667             0 
length(offers$salarioMax)
[1] 40533
levels(offers$comunidadF)
 [1] ""                       "ANDALUCÃ�A"             "ANDALUCÍA"             
 [4] "ARAGÓN"                "ARAGÓN"                 "CANTABRIA"             
 [7] "CASTILLA LA MANCHA"     "CASTILLA Y LEÓN"       "CASTILLA Y LEÓN"       
[10] "CASTILLA Y LE��N"       "CATALUÑA"              "CATALUÑA"              
[13] "CATALU��A"              "CEUTA"                  "COMUNIDAD VALENCIANA"  
[16] "EXTREMADURA"            "GALICIA"                "ILLES BALEARS"         
[19] "ISLAS CANARIAS"         "LA RIOJA"               "MADRID"                
[22] "MELILLA"                "NAVARRA"                "PA�S VASCO"           
[25] "PAÍS VASCO"             "PRINCIPADO DE ASTURIAS" "REGIÓN DE MURCIA"     
[28] "REGIÓN DE MURCIA"       "REGI��N DE MURCIA"      "Sin especificar"       
offers$comunidadF <- sub("ARAGÓN", "ARAGÓN", offers$comunidadF)
offers$comunidadF <- sub("CASTILLA Y LE��N", "CASTILLA Y LEÓN", offers$comunidadF)
offers$comunidadF <- sub("CASTILLA Y LEÓN", "CASTILLA Y LEÓN", offers$comunidadF)
offers$comunidadF <- sub("CATALU��A", "CATALUÑA", offers$comunidadF)
offers$comunidadF <- sub("CATALUÑA", "CATALUÑA", offers$comunidadF)
offers$comunidadF <- sub("ANDALUCÃ�A", "ANDALUCÍA", offers$comunidadF)
offers$comunidadF <- sub("REGI��N DE MURCIA", "REGIÓN DE MURCIA", offers$comunidadF)
offers$comunidadF <- sub("REGIÓN DE MURCIA", "REGIÓN DE MURCIA", offers$comunidadF)
offers$comunidadF <- sub("PAÃ�S VASCO", "PAÍS VASCO", offers$comunidadF)
offers$comunidadF <- sub("Sin especificar", "", offers$comunidadF)
offers$comunidadF <- factor(offers$comunidadF)
levels(offers$comunidadF)
 [1] ""                       "ANDALUCÍA"              "ARAGÓN"                
 [4] "CANTABRIA"              "CASTILLA LA MANCHA"     "CASTILLA Y LEÓN"       
 [7] "CATALUÑA"               "CEUTA"                  "COMUNIDAD VALENCIANA"  
[10] "EXTREMADURA"            "GALICIA"                "ILLES BALEARS"         
[13] "ISLAS CANARIAS"         "LA RIOJA"               "MADRID"                
[16] "MELILLA"                "NAVARRA"                "PAÍS VASCO"            
[19] "PRINCIPADO DE ASTURIAS" "REGIÓN DE MURCIA"      

Veiem que en aquest cas podem tenir valor buit (“”) o sin especificar. Ens interessa deixar els dos casos, ja que sin especificar pot ser una

TODO: Descriure millor com utilitzarem els casos buits.

# offers[which(offers$comunidadF == "CATALUÑA"),]
levels(offers$categoriaF)
 [1] ""                                     "ADMINISTRACIÓN"                     
 [3] "ADMINISTRACIÓN"                       "AGRICULTURA/JARDINERÍA/ALIMENTACIÓN" 
 [5] "ALMACENES/REPONEDORES"                "APRENDICES/PRIMER EMPLEO"            
 [7] "ARQUITECTURA/DISEÑO"                  "COMERCIAL/VENTAS"                    
 [9] "COMUNICACIÓN/CULTURA/ENTRETENIMIENTO" "CONDUCTORES/TRANSPORTE"              
[11] "CONSTRUCCIÓN"                         "CONSTRUCCI��N"                       
[13] "CUIDADOS/ASISTENCIA EN EL HOGAR"      "DEPENDIENTES/INFORMACIÓN"            
[15] "DERECHO/PSICOLOGÍA/CIENCIAS SOCIALES" "DIRECTIVOS"                          
[17] "EDUCACIÓN/SERVICIOS SOCIALES"        "EDUCACIÓN/SERVICIOS SOCIALES"        
[19] "EDUCACI��N/SERVICIOS SOCIALES"        "ELECTRICIDAD/ELECTRÓNICA/ENERGÍA"    
[21] "ELECTRICIDAD/ELECTR��NICA/ENERG��A"   "FÁBRICAS/INDUSTRIA"                  
[23] "FÃ�BRICAS/INDUSTRIA"                  "HOSTELERÍA/TURISMO"                  
[25] "HOSTELER��A/TURISMO"                  "INFORMÁTICA/TELECOMUNICACIONES"      
[27] "INFORM�TICA/TELECOMUNICACIONES"      "INFORM��TICA/TELECOMUNICACIONES"     
[29] "INGENIERÃ�A/CALIDAD/CIENCIAS"         "INGENIERÍA/CALIDAD/CIENCIAS"         
[31] "METAL/MECÁNICA"                       "METAL/MECÃ�NICA"                     
[33] "PELUQUERÍA/ESTÉTICA"                  "SALUD/DEPORTE"                       
[35] "VIGILANCIA/SERVICIOS"                

En comptes de corregir un a un, transformarem les dades al format latin1.

# convertim les dades a encoding latin1
offers$categoriaF <- factor(iconv(offers$categoriaF, to = "latin1"))
levels(offers$categoriaF)
 [1] ""                                     "ADMINISTRACIÓN"                      
 [3] "AGRICULTURA/JARDINERÍA/ALIMENTACIÓN"  "ALMACENES/REPONEDORES"               
 [5] "APRENDICES/PRIMER EMPLEO"             "ARQUITECTURA/DISEÑO"                 
 [7] "COMERCIAL/VENTAS"                     "COMUNICACIÓN/CULTURA/ENTRETENIMIENTO"
 [9] "CONDUCTORES/TRANSPORTE"               "CONSTRUCCIÓN"                        
[11] "CUIDADOS/ASISTENCIA EN EL HOGAR"      "DEPENDIENTES/INFORMACIÓN"            
[13] "DERECHO/PSICOLOGÍA/CIENCIAS SOCIALES" "DIRECTIVOS"                          
[15] "EDUCACIÓN/SERVICIOS SOCIALES"         "ELECTRICIDAD/ELECTRÓNICA/ENERGÍA"    
[17] "FÁBRICAS/INDUSTRIA"                   "HOSTELERÍA/TURISMO"                  
[19] "INFORMÁTICA/TELECOMUNICACIONES"       "INGENIERÍA/CALIDAD/CIENCIAS"         
[21] "METAL/MECÁNICA"                       "PELUQUERÍA/ESTÉTICA"                 
[23] "SALUD/DEPORTE"                        "VIGILANCIA/SERVICIOS"                

TODO: Revisar provincias!!! Guipuzcua esta repetida!!!!

# offers[which(offers$comunidadF == "CATALUÑA"),]
levels(offers$provinciaS)
# offers[which(offers$comunidadF == "CATALUÑA"),]
levels(offers$jornadaF)
[1] ""            "COMPLETA"    "INDIFERENTE" "PARCIAL"    
# offers[which(offers$comunidadF == "CATALUÑA"),]
# convertim les dades a encoding latin1
offers$subcategoriaS <- factor(iconv(offers$subcategoriaS, to = "latin1"))
levels(offers$subcategoriaS)
  [1] ""                                         "ABOGADOS"                                
  [3] "ACUICULTURA"                              "ADMINISTRATIVOS"                         
  [5] "AGENCIA DE VIAJES"                        "AGENTES COMERCIALES/REPRESENTANTES"      
  [7] "AGRICULTURA/GANADERÍA"                    "ALBAÑILERIA/ACABADOS"                    
  [9] "ANALISTAS/PROGRAMADORES"                  "ANIMACIÓN TURÍSTICA"                     
 [11] "ANIMACIÓN/TIEMPO LIBRE"                   "APRENDICES"                              
 [13] "APUESTAS Y JUEGO"                         "AREA DIRECTIVA"                          
 [15] "ARQUITECTOS"                              "ARTE/CULTURA/ESPECTÁCULOS"               
 [17] "ARTESANÍA/OFICIOS"                        "ASISTENCIA E INTEGRACIÓN SOCIAL"         
 [19] "AUXILIARES DE ENFERMERÍA/GERIATRÍA"       "AUXILIARES DE SERVICIO/PERSONAL SUBALTER"
 [21] "AYUDA DOMICILIARIA"                       "AYUDANTES DE COCINA/COMIDA RÁPIDA"       
 [23] "BANCA/SEGUROS"                            "BIBLIOTECAS/ARCHIVOS/MUSEOS"             
 [25] "BUCEADORES"                               "CAJEROS SUPERMERCADO"                    
 [27] "CAJEROS Y TAQUILLEROS"                    "CALIDAD"                                 
 [29] "CAMAREROS"                                "CARNICERÍA/CHARCUTERIA"                  
 [31] "CARPINTERÍA"                              "CERRAJEROS/FORJA/HERREROS"               
 [33] "COCINEROS"                                "COMERCIO EXTERIOR"                       
 [35] "COMPRAS/DISTRIBRUCIÓN"                    "COMUNICACIÓN/PUBLICIDAD/MARKETING"       
 [37] "CONSERVAS/ALIMENTOS/BEBIDAS"              "CONTABILIDAD/FINANZAS"                   
 [39] "CRISTALEROS"                              "CUIDADO DE ANCIANOS/NIÑOS"               
 [41] "CUIDADORES Y ADIESTRADORES DE ANIMALES"   "DECORADORES"                             
 [43] "DELINEANTES/PROYECTISTAS"                 "DEPENDIENTES"                            
 [45] "DIETÉTICA Y NUTRICIÓN"                    "DISEÑO GRÁFICO/WEB"                      
 [47] "DISEÑO INDUSTRIAL"                        "ECONOMISTAS"                             
 [49] "EDICIÓN/INDUSTRIA GRÁFICA"                "EDUCACIÓN ESPECIAL/PEDAGOGÍA"            
 [51] "EDUCACIÓN INFANTIL"                       "ELECTRICIDAD"                            
 [53] "ELECTRÓNICA"                              "ENCARGADOS DE OBRAS/CAPATACES"           
 [55] "ENCARGADOS Y SUPERVISORES DE PRODUCCIÓN"  "ENCOFRADO/FERRALLA/ESTRUCTURAS"          
 [57] "ENCUESTADORES"                            "ENERGÍAS RENOVABLES"                     
 [59] "ENFERMERÍA"                               "ENSEÑANZA DE IDIOMAS"                    
 [61] "ENSEÑANZA PRIMARIA Y SECUNDARIA"          "ERP/CRM/BUSSINESS INTELLIGENCE"          
 [63] "ESTÉTICA"                                 "FARMACIA/ÓPTICA/AUDICIÓN"                
 [65] "FISIOTERAPIA/DEPORTE/MANTENIMIENTO FISIC" "FONTANERÍA"                              
 [67] "FORESTAL/JARDINERÍA"                      "FORMACIÓN PROFESIONAL"                   
 [69] "FRÍO Y CLIMATIZACIÓN"                     "FUNDICIÓN/SIDERURGÍA"                    
 [71] "GESTIÓN DE ALMACENES"                     "GESTIÓN DE PROYECTOS"                    
 [73] "GRÚAS/EXCAVADORAS/MAQUINARIA"             "I+D"                                     
 [75] "IMAGEN Y SONIDO/AUDIOVISUAL"              "INFORMACIÓN/AZAFATAS/PROMOCIÓN COMERCIAL"
 [77] "INGENIERÍAS"                              "LIMPIEZA"                                
 [79] "MADERA Y MUEBLE/EBANISTERÍA"              "MAQUINA HERRAMIENTA/TORNO/FRESA"         
 [81] "MECÁNICA DEL AUTOMÓVIL"                   "MECÁNICA/MANTENIMIENTO"                  
 [83] "MEDICINA"                                 "MEDIO AMBIENTE/QUÍMICA/BIOLOGÍA/LABORATO"
 [85] "MENSAJERÍA"                               "MICROINFORMATICA/ASISTENCIA TÉCNICA"     
 [87] "MINAS/CANTERAS/PERFORACIONES"             "MONTADORES Y ENSAMBLADORES"              
 [89] "MOZOS DE ALMACÉN/CARRETILLEROS"           "NAVEGACIÓN"                              
 [91] "ORDENANZAS/CONSERJES"                     "OTRAS ACTIVIDADES"                       
 [93] "OTRAS ACTIVIDADES TÉCNICAS"               "OTROS PROFESIONALES"                     
 [95] "PANADERÍA/REPOSTERÍA"                     "PELUQUERÍA"                              
 [97] "PEONES"                                   "PEONES/OPERARIOS/MANIPULADORES"          
 [99] "PERIODISMO E INFORMACIÓN"                 "PESCA"                                   
[101] "PINTURA"                                  "POMPAS FUNEBRES"                         
[103] "PREVENCIÓN RIESGOS LABORALES"             "PRIMER EMPLEO"                           
[105] "PRODUCCIÓN Y DISTRIBUCCIÓN DE ENERGIA"    "PROFESORES DE ENSEÑANZA SUPERIOR"        
[107] "PSICÓLOGOS"                               "RECEPCIONISTAS"                          
[109] "RECEPCIONISTAS DE HOTEL"                  "RECURSOS HUMANOS/PERSONAL"               
[111] "REPARTO DE MERCANCÍAS"                    "REPONEDORES"                             
[113] "SALUD DENTAL"                             "SECRETARIADO"                            
[115] "SEGURIDAD"                                "SERVICIO DOMÉSTICO"                      
[117] "SERVICIOS VETERINARIOS"                   "SISTEMAS/SEGURIDAD/REDES"                
[119] "SOCIÓLOGOS"                               "SOLDADURA/CALDERERÍA/CHAPA"              
[121] "TECNICOS EN CONSTRUCCION"                 "TECNICOS METALURGICOS"                   
[123] "TELECOMUNICACIONES"                       "TELEOPERADORES"                          
[125] "TEXTIL/CONFECCIÓN/CALZADO"                "TOPOGRAFÍA"                              
[127] "TRANSPORTE AÉREO"                         "TRANSPORTE DE PERSONAS O MERCANCIAS"     
[129] "TRANSPORTE INTERNACIONAL/ESPECIAL"        "VENDEDORES"                              
[131] "VIGILANCIA/GUARDAS JURADOS"              
# offers[which(offers$comunidadF == "CATALUÑA"),]
# convertim les dades a encoding latin1
offers$educacionF <- factor(iconv(offers$educacionF, to = "latin1"))
levels(offers$educacionF)
 [1] ""                                "Bachillerato"                   
 [3] "Certificados de Profesionalidad" "Diplomado o Ingeniero Técnico" 
 [5] "Diplomado o Ingeniero Técnico"   "Doctor Universitario"           
 [7] "ESO, EGB, Graduado Escolar"      "Estudios primarios"             
 [9] "FP I, Ciclo de Grado Medio"      "FP II, Ciclo de Grado Superior" 
[11] "Licenciado o Ingeniero Superior" "Otras Formaciones"              
[13] "Postgrado Universitario"         "Sin especificar"                
[15] "Sin estudios"                   

Tot i la conversió, encara tenim algun cas que no s’ha codificat correctament. El corregirem manualment.

offers$educacionF <- sub("Diplomado o Ingeniero Técnico", "Diplomado o Ingeniero Técnico", offers$educacionF)
offers$educacionF <- factor(offers$educacionF)
levels(offers$educacionF)
 [1] ""                                "Bachillerato"                   
 [3] "Certificados de Profesionalidad" "Diplomado o Ingeniero Técnico"  
 [5] "Doctor Universitario"            "ESO, EGB, Graduado Escolar"     
 [7] "Estudios primarios"              "FP I, Ciclo de Grado Medio"     
 [9] "FP II, Ciclo de Grado Superior"  "Licenciado o Ingeniero Superior"
[11] "Otras Formaciones"               "Postgrado Universitario"        
[13] "Sin especificar"                 "Sin estudios"                   

Passem ara a netejar les característiques numériques. Veiem que aproximadament una quarta part de les dades dispossen de valors de salari mínim i máxim. Aquests ens podrien ser suficient per al nostres estudi, sempre i quan tinguem suficient casos d’estudi per a les diferentes regions.

Llavors, ens quedarem amb les dades que tenen un salari mínim i descartarem la resta. Com que hi ha menys dades amb salari máxim, aquest l’imputarem utilitzant knn.

offers_sp <- subset(offers, !is.na(offers$salarioMin))
sapply(offers_sp, function(x)(sum(is.na(x))))
   categoriaF       ciudadF    comunidadF    educacionF fechaCreacion      jornadaF         paisS 
            4             0             0             0             0             0             0 
   provinciaS    salarioMax    salarioMin subcategoriaS 
            0          6420             0             2 
offers_sp$salarioMax <- kNN(offers_sp)$salarioMax
sapply(offers_sp, function(x)(sum(is.na(x))))
   categoriaF       ciudadF    comunidadF    educacionF fechaCreacion      jornadaF         paisS 
            4             0             0             0             0             0             0 
   provinciaS    salarioMax    salarioMin subcategoriaS 
            0             0             0             2 

Ara només ens queden per tractar 4 casos de categoriaF i 2 de subcategoriaS.

kable(subset(offers_sp, is.na(offers_sp$categoriaF)))
categoriaF ciudadF comunidadF educacionF fechaCreacion jornadaF paisS provinciaS salarioMax salarioMin subcategoriaS
32704 NA Las Palmas de Gran Canaria ISLAS CANARIAS Otras Formaciones 2018-06-05T16:50:28Z PARCIAL ESPAÑA PALMAS (LAS) 1000 600 NA
32705 NA Bilbao PAÍS VASCO Licenciado o Ingeniero Superior 2018-03-02T08:33:14Z COMPLETA ESPAÑA VIZCAYA 25000 20000 NA
32706 NA Bilbao PAÍS VASCO FP II, Ciclo de Grado Superior 2018-03-02T08:27:33Z COMPLETA ESPAÑA VIZCAYA 25000 20000 SISTEMAS/SEGURIDAD/REDES
32707 NA Bilbao PAÍS VASCO FP II, Ciclo de Grado Superior 2018-03-02T08:15:32Z COMPLETA ESPAÑA VIZCAYA 25000 20000 ANALISTAS/PROGRAMADORES

Mirant la subcategoria, veiem clarament que les dues últimes pertanyen a la categoria: INFORMÁTICA/TELECOMUNICACIONES, però malauradament, les dues primeres no tenen subcategoria. Així doncs, descartarem les dues primeres i ens quedarem amb les dues últimes, introduint el nou valor a la categoria.

offers_sp <- subset(offers_sp, !is.na(offers_sp$subcategoriaS))
sapply(offers_sp, function(x)(sum(is.na(x))))
   categoriaF       ciudadF    comunidadF    educacionF fechaCreacion      jornadaF         paisS 
            2             0             0             0             0             0             0 
   provinciaS    salarioMax    salarioMin subcategoriaS 
            0             0             0             0 

Com que nomès ens queden dos valors NA per substituir i son els que coneixem, podem fer la següent operació.

offers_sp[is.na(offers_sp)] <- c("INFORMÁTICA/TELECOMUNICACIONES")
sapply(offers_sp, function(x)(sum(is.na(x))))
   categoriaF       ciudadF    comunidadF    educacionF fechaCreacion      jornadaF         paisS 
            0             0             0             0             0             0             0 
   provinciaS    salarioMax    salarioMin subcategoriaS 
            0             0             0             0 

Comprovem que ja no tenim cap valor NA.

summary(offers_sp)
                          categoriaF        ciudadF                    comunidadF  
 INFORMÁTICA/TELECOMUNICACIONES:1322            :1457   CATALUÑA            :3432  
 COMERCIAL/VENTAS              : 980   Barcelona:1037   MADRID              :1593  
 ADMINISTRACIÓN                : 724   Madrid   : 968   ANDALUCÍA           :1205  
 SALUD/DEPORTE                 : 639   Girona   : 188   COMUNIDAD VALENCIANA: 511  
 HOSTELERÍA/TURISMO            : 579   Valencia : 121   CASTILLA Y LEÓN     : 327  
 CONSTRUCCIÓN                  : 515   Sevilla  : 104   GALICIA             : 297  
 (Other)                       :4105   (Other)  :4989   (Other)             :1499  
                          educacionF                fechaCreacion         jornadaF       paisS     
                               :3934   2018-09-20T10:10:36Z:  25              :1987   ESPAÑA:8864  
 FP II, Ciclo de Grado Superior:1508   2018-10-23T15:23:57Z:  17   COMPLETA   :5402                
 ESO, EGB, Graduado Escolar    : 572   2018-10-26T15:08:28Z:  17   INDIFERENTE: 185                
 Sin especificar               : 549   2018-11-01T00:08:47Z:  16   PARCIAL    :1290                
 FP I, Ciclo de Grado Medio    : 545   2018-11-03T00:08:37Z:  16                                   
 Diplomado o Ingeniero Técnico : 543   2018-10-26T14:04:15Z:  11                                   
 (Other)                       :1213   (Other)             :8762                                   
     provinciaS     salarioMax        salarioMin                                subcategoriaS 
 BARCELONA:2527   Min.   :      0   Min.   :     0   AGENTES COMERCIALES/REPRESENTANTES: 781  
 MADRID   :1577   1st Qu.:   1200   1st Qu.:  1000                                     : 554  
 GIRONA   : 411   Median :   1600   Median :  1700   ANALISTAS/PROGRAMADORES           : 417  
 VALENCIA : 284   Mean   :  12078   Mean   : 10091   ENFERMERÍA                        : 360  
 TARRAGONA: 283   3rd Qu.:  19000   3rd Qu.: 18000   ADMINISTRATIVOS                   : 327  
 SEVILLA  : 262   Max.   :9999999   Max.   :105000   PEONES/OPERARIOS/MANIPULADORES    : 257  
 (Other)  :3520                                      (Other)                           :6168  

Seguidament podriem comprovar si les nostres dades tenen el tipus que desitjem.

sapply(offers_sp, function(x)(class(x)))
   categoriaF       ciudadF    comunidadF    educacionF fechaCreacion      jornadaF         paisS 
     "factor"      "factor"      "factor"      "factor"      "factor"      "factor"      "factor" 
   provinciaS    salarioMax    salarioMin subcategoriaS 
     "factor"     "numeric"     "numeric"      "factor" 

Veiem que haurem de tractar el format de la característica fechaCreacion. En aquest moment, tenim la data com a un string amb el format: anys, mes, dia, hora. En el nostre cas, nomès amb l’any, mes i dia en tindrem prou. A més, haurem de donar-li el tipus de date type.

offers_sp$fechaCreacion <- as.Date(gsub("T\\d*:\\d*:\\d*Z", "", offers_sp$fechaCreacion))
sapply(offers_sp, function(x)(class(x)))
   categoriaF       ciudadF    comunidadF    educacionF fechaCreacion      jornadaF         paisS 
     "factor"      "factor"      "factor"      "factor"        "Date"      "factor"      "factor" 
   provinciaS    salarioMax    salarioMin subcategoriaS 
     "factor"     "numeric"     "numeric"      "factor" 
summary(offers_sp)
                          categoriaF        ciudadF                    comunidadF  
 INFORMÁTICA/TELECOMUNICACIONES:1322            :1457   CATALUÑA            :3432  
 COMERCIAL/VENTAS              : 980   Barcelona:1037   MADRID              :1593  
 ADMINISTRACIÓN                : 724   Madrid   : 968   ANDALUCÍA           :1205  
 SALUD/DEPORTE                 : 639   Girona   : 188   COMUNIDAD VALENCIANA: 511  
 HOSTELERÍA/TURISMO            : 579   Valencia : 121   CASTILLA Y LEÓN     : 327  
 CONSTRUCCIÓN                  : 515   Sevilla  : 104   GALICIA             : 297  
 (Other)                       :4105   (Other)  :4989   (Other)             :1499  
                          educacionF   fechaCreacion               jornadaF       paisS     
                               :3934   Min.   :2016-04-08              :1987   ESPAÑA:8864  
 FP II, Ciclo de Grado Superior:1508   1st Qu.:2018-05-30   COMPLETA   :5402                
 ESO, EGB, Graduado Escolar    : 572   Median :2018-09-04   INDIFERENTE: 185                
 Sin especificar               : 549   Mean   :2018-07-03   PARCIAL    :1290                
 FP I, Ciclo de Grado Medio    : 545   3rd Qu.:2018-10-11                                   
 Diplomado o Ingeniero Técnico : 543   Max.   :2018-11-04                                   
 (Other)                       :1213                                                        
     provinciaS     salarioMax        salarioMin                                subcategoriaS 
 BARCELONA:2527   Min.   :      0   Min.   :     0   AGENTES COMERCIALES/REPRESENTANTES: 781  
 MADRID   :1577   1st Qu.:   1200   1st Qu.:  1000                                     : 554  
 GIRONA   : 411   Median :   1600   Median :  1700   ANALISTAS/PROGRAMADORES           : 417  
 VALENCIA : 284   Mean   :  12078   Mean   : 10091   ENFERMERÍA                        : 360  
 TARRAGONA: 283   3rd Qu.:  19000   3rd Qu.: 18000   ADMINISTRATIVOS                   : 327  
 SEVILLA  : 262   Max.   :9999999   Max.   :105000   PEONES/OPERARIOS/MANIPULADORES    : 257  
 (Other)  :3520                                      (Other)                           :6168  

Per últim, podem canviar el nombre de les característiques per que tinguin una mica més de sentit i guardem les dades en un nou fitxer csv.

names(offers_sp)
 [1] "categoriaF"    "ciudadF"       "comunidadF"    "educacionF"    "fechaCreacion" "jornadaF"     
 [7] "paisS"         "provinciaS"    "salarioMax"    "salarioMin"    "subcategoriaS"
final_names <- c("Categoria", "Ciudad", "Comunidad", "Educacion", "FechaCreacion", "TipoJornada", "Pais", "Provincia", "SalarioMax", "SalarioMin", "SubCategoria")
names(offers_sp) <- final_names
head(offers_sp)

Veiem també que ja no necessitem la variable Pais. Podriem eliminar-la.

offers_sp$Pais <- NULL
names(offers_sp)
 [1] "Categoria"     "Ciudad"        "Comunidad"     "Educacion"     "FechaCreacion" "TipoJornada"  
 [7] "Provincia"     "SalarioMax"    "SalarioMin"    "SubCategoria" 
tail(offers_sp)

Per últim, podriem exportar el nostre conjunt de dades netejat.

write.csv(offers_sp, "./data/spanish_job_offers_clean.csv")

Identificació i tractament de valors extrems.

Donem ara un cop d’ull a les dades per tal d’identificar valors extrems.

boxplot(offers_sp$SalarioMin)

boxplot(offers_sp$SalarioMax)

boxplot(offers_sp$SalarioMin ~ offers_sp$Comunidad)

boxplot(offers_sp$SalarioMax ~ offers_sp$Comunidad)

boxplot.stats(offers_sp$SalarioMin)$out
  [1]  46200  60000 100000  82000  50000  94000  50000  70000  92019 100000  50000  65000  65000
 [14]  45000  45000 105000  65000 104000  45000  45000  50000  50000  45000  46460  45000  48000
 [27]  45000  60000  45000  45000  60000  45000  45000  50000  48000  45000  50000  48000  45000
 [40]  45000  50000  45000 100000 100000 100000 100000 100000 100000 100000 100000 100000 100000
 [53]  51000  51000  51000  51000  51000  51000  51000  51000  51000  51000  51000  51000  51000
 [66]  51000  51000  51000  51000  51000  51000  51000  51000  51000  51000  51000  51000  51000
 [79]  51000  51000  51000  51000 100000 100000 100000 100000 100000 100000 100000 100000 100000
 [92] 100000 100000 100000 100000 100000 100000  45000  51000  51000  68000  68000  68000  68000
[105]  68000  68000  68000  68000  68000  68000  68000  68000  68000  68000  68000  68000  68000
[118]  68000  68000  68000  68000  68000  68000  68000  68000  68000  68000  68000  68000  68000
[131]  68000  68000  68000  68000  68000  68000  68000  68000  68000  68000  68000  68000  68000
[144]  68000  68000  68000  68000  68000  68000  68000  68000  68000  45000  45000  45000  45000
[157]  45000  45000  45000  45000  45000  45000  45000  45000  45000  45000  45000  45000  45000
[170]  45000  45000  45000  45000  45000  45000  45000  45000  45000  45000  45000  45000  45000
[183]  45000  45000  45000  45000  45000  45000  45000  45000  45000  45000  45000  45000  45000
[196]  45000  45000  45000  45000  45000  45000  45000  45000  45000  46200
boxplot.stats(offers_sp$SalarioMax)$out
 [1]   85800   65000   65000   50000   50000   60000   50000   50000   50000   50000  340000   50000
[13]   50000   65000   50000   50000 9999999  200000 9999999   50000   60000   50000   50000   60000
[25]   50000  220000  100000   50000   85800

Veiem que tenim valors extrems tant en els salaris màxims com en els mínims. En el cas dels salaris mínims, son valor raonables, i crec que els hauriem de deixar tal qual son. En canvi, trobem dos valors extrems molt curiosos, que semblen ser alguna mena de valor prefixat per a no donar un límit superior. En aquest cas, ja que son només dos valors i tenim suficient dades per al nostre estudi, considero que lo millor sería treure les dades corresponents. Així doncs, ho farem de la següent manera.

kable(subset(offers_sp, SalarioMax == 9999999))
Categoria Ciudad Comunidad Educacion FechaCreacion TipoJornada Provincia SalarioMax SalarioMin SubCategoria
17853 COMERCIAL/VENTAS Madrid MADRID Sin especificar 2018-09-11 INDIFERENTE MADRID 9999999 0 AGENTES COMERCIALES/REPRESENTANTES
18691 COMERCIAL/VENTAS Sevilla ANDALUCÍA Sin especificar 2018-09-11 INDIFERENTE SEVILLA 9999999 0 AGENTES COMERCIALES/REPRESENTANTES
kable(subset(offers_sp, SalarioMin == 0))
Categoria Ciudad Comunidad Educacion FechaCreacion TipoJornada Provincia SalarioMax SalarioMin SubCategoria
103 CONSTRUCCIÓN San Sebastián de los Reyes MADRID Otras Formaciones 2018-10-22 COMPLETA MADRID 1000 0 ALBAÑILERIA/ACABADOS
1036 INFORMÁTICA/TELECOMUNICACIONES Pamplona/Iruña NAVARRA FP II, Ciclo de Grado Superior 2018-10-29 COMPLETA NAVARRA 0 0 ERP/CRM/BUSSINESS INTELLIGENCE
1044 CONSTRUCCIÓN La Pobla de Vallbona COMUNIDAD VALENCIANA Sin especificar 2018-10-29 COMPLETA VALENCIA 0 0 PINTURA
3148 CONSTRUCCIÓN Tarancón CASTILLA LA MANCHA Sin estudios 2018-10-26 COMPLETA CUENCA 1500 0 FONTANERÍA
4721 SALUD/DEPORTE Benalmádena ANDALUCÍA Doctor Universitario 2018-10-26 INDIFERENTE MÁLAGA 0 0 SALUD DENTAL
4722 SALUD/DEPORTE Benalmádena ANDALUCÍA Diplomado o Ingeniero Técnico 2018-10-26 PARCIAL MÁLAGA 0 0 FISIOTERAPIA/DEPORTE/MANTENIMIENTO FISIC
4971 HOSTELERÍA/TURISMO Vila de Cruces GALICIA Sin especificar 2018-10-25 PARCIAL PONTEVEDRA 0 0 CAMAREROS
5312 COMERCIAL/VENTAS Madrid MADRID Sin especificar 2018-10-24 COMPLETA MADRID 0 0 AGENTES COMERCIALES/REPRESENTANTES
5990 CONSTRUCCIÓN Santander CANTABRIA Sin especificar 2018-10-24 COMPLETA CANTABRIA 0 0 ALBAÑILERIA/ACABADOS
6718 CONSTRUCCIÓN Boadilla del Monte MADRID Sin especificar 2018-10-24 COMPLETA MADRID 0 0 ENCARGADOS DE OBRAS/CAPATACES
7043 AGRICULTURA/JARDINERÍA/ALIMENTACIÓN Sant Joan d’Alacant COMUNIDAD VALENCIANA ESO, EGB, Graduado Escolar 2018-10-23 PARCIAL ALICANTE 1200 0 FORESTAL/JARDINERÍA
7637 CONSTRUCCIÓN Madrid MADRID Bachillerato 2018-05-21 COMPLETA MADRID 0 0 ENCARGADOS DE OBRAS/CAPATACES
7938 CONSTRUCCIÓN La Pobla de Vallbona COMUNIDAD VALENCIANA Sin especificar 2018-10-22 COMPLETA VALENCIA 0 0 FONTANERÍA
8308 CONSTRUCCIÓN Torrent COMUNIDAD VALENCIANA Sin especificar 2018-10-22 COMPLETA VALENCIA 0 0 ALBAÑILERIA/ACABADOS
8348 CONSTRUCCIÓN Torrent COMUNIDAD VALENCIANA Sin especificar 2018-10-22 COMPLETA VALENCIA 0 0 ALBAÑILERIA/ACABADOS
8920 FÁBRICAS/INDUSTRIA Beniparrell COMUNIDAD VALENCIANA Sin especificar 2018-10-19 INDIFERENTE VALENCIA 0 0 MADERA Y MUEBLE/EBANISTERÍA
9295 AGRICULTURA/JARDINERÍA/ALIMENTACIÓN Valencia COMUNIDAD VALENCIANA Sin especificar 2018-10-19 COMPLETA VALENCIA 2000 0 PANADERÍA/REPOSTERÍA
9862 CONSTRUCCIÓN Albacete CASTILLA LA MANCHA Sin especificar 2018-10-18 COMPLETA ALBACETE 0 0 ENCOFRADO/FERRALLA/ESTRUCTURAS
10258 PELUQUERÍA/ESTÉTICA Sagunto/Sagunt COMUNIDAD VALENCIANA FP I, Ciclo de Grado Medio 2018-10-17 PARCIAL VALENCIA 0 0 ESTÉTICA
10508 PELUQUERÍA/ESTÉTICA Valladolid CASTILLA Y LEÓN FP I, Ciclo de Grado Medio 2018-10-17 COMPLETA VALLADOLID 1500 0 ESTÉTICA
11225 INFORMÁTICA/TELECOMUNICACIONES Bétera COMUNIDAD VALENCIANA FP II, Ciclo de Grado Superior 2018-09-25 INDIFERENTE VALENCIA 1000 0 ANALISTAS/PROGRAMADORES
11444 ALMACENES/REPONEDORES Torrelavega CANTABRIA Estudios primarios 2018-10-16 COMPLETA CANTABRIA 0 0 MOZOS DE ALMACÉN/CARRETILLEROS
11561 COMUNICACIÓN/CULTURA/ENTRETENIMIENTO Torrelavega CANTABRIA Bachillerato 2018-10-16 PARCIAL CANTABRIA 0 0 ARTE/CULTURA/ESPECTÁCULOS
11905 ELECTRICIDAD/ELECTRÓNICA/ENERGÍA Torrejón de Ardoz MADRID FP II, Ciclo de Grado Superior 2018-10-16 COMPLETA MADRID 0 0 ELECTRÓNICA
12521 APRENDICES/PRIMER EMPLEO Madrid MADRID Estudios primarios 2018-06-28 COMPLETA MADRID 0 0 APRENDICES
12549 AGRICULTURA/JARDINERÍA/ALIMENTACIÓN ESO, EGB, Graduado Escolar 2018-10-14 COMPLETA 0 0 AGRICULTURA/GANADERÍA
13047 ADMINISTRACIÓN Madrid MADRID Diplomado o Ingeniero Técnico 2017-02-27 COMPLETA MADRID 0 0 RECURSOS HUMANOS/PERSONAL
13493 ADMINISTRACIÓN Barcelona CATALUÑA Sin especificar 2018-10-04 COMPLETA BARCELONA 1305 0 ADMINISTRATIVOS
13784 EDUCACIÓN/SERVICIOS SOCIALES Diplomado o Ingeniero Técnico 2018-10-04 PARCIAL 0 0 FORMACIÓN PROFESIONAL
13818 FÁBRICAS/INDUSTRIA Laviana PRINCIPADO DE ASTURIAS Sin especificar 2018-10-04 COMPLETA ASTURIAS 0 0 PEONES/OPERARIOS/MANIPULADORES
13914 ALMACENES/REPONEDORES Picassent COMUNIDAD VALENCIANA ESO, EGB, Graduado Escolar 2018-10-04 INDIFERENTE VALENCIA 1200 0 GESTIÓN DE ALMACENES
13946 CUIDADOS/ASISTENCIA EN EL HOGAR Tres Cantos MADRID Sin estudios 2018-10-04 PARCIAL MADRID 950 0 LIMPIEZA
14386 ELECTRICIDAD/ELECTRÓNICA/ENERGÍA Reus CATALUÑA FP I, Ciclo de Grado Medio 2018-06-21 COMPLETA TARRAGONA 1100 0 ELECTRICIDAD
14662 DEPENDIENTES/INFORMACIÓN Bétera COMUNIDAD VALENCIANA Bachillerato 2018-09-27 PARCIAL VALENCIA 600 0 TELEOPERADORES
15534 AGRICULTURA/JARDINERÍA/ALIMENTACIÓN Cuéllar CASTILLA Y LEÓN Sin estudios 2018-09-28 COMPLETA SEGOVIA 900 0 FORESTAL/JARDINERÍA
15578 COMERCIAL/VENTAS Pego COMUNIDAD VALENCIANA FP I, Ciclo de Grado Medio 2018-09-28 COMPLETA ALICANTE 0 0 VENDEDORES
15686 ADMINISTRACIÓN Leganés MADRID FP I, Ciclo de Grado Medio 2017-10-02 COMPLETA MADRID 0 0 CONTABILIDAD/FINANZAS
15706 ADMINISTRACIÓN Pamplona/Iruña NAVARRA Licenciado o Ingeniero Superior 2018-09-27 COMPLETA NAVARRA 0 0 ADMINISTRATIVOS
15760 METAL/MECÁNICA Paracuellos de Jarama MADRID Sin especificar 2018-09-27 COMPLETA MADRID 0 0 CERRAJEROS/FORJA/HERREROS
15822 ADMINISTRACIÓN Madrid MADRID Bachillerato 2018-09-27 PARCIAL MADRID 0 0 ADMINISTRATIVOS
16704 ADMINISTRACIÓN Leganés MADRID Bachillerato 2018-05-21 COMPLETA MADRID 0 0 ADMINISTRATIVOS
16906 COMERCIAL/VENTAS Santander CANTABRIA ESO, EGB, Graduado Escolar 2018-09-20 COMPLETA CANTABRIA 1000 0 VENDEDORES
17298 CONDUCTORES/TRANSPORTE ESO, EGB, Graduado Escolar 2018-09-19 COMPLETA 0 0 REPARTO DE MERCANCÍAS
17531 CONDUCTORES/TRANSPORTE Valdeltormo ARAGÓN Sin especificar 2018-09-18 COMPLETA TERUEL 0 0 REPARTO DE MERCANCÍAS
17854 CONSTRUCCIÓN Las Palmas de Gran Canaria ISLAS CANARIAS Sin especificar 2018-09-17 COMPLETA PALMAS (LAS) 0 0 CARPINTERÍA
17880 COMERCIAL/VENTAS Madrid MADRID Bachillerato 2018-09-17 INDIFERENTE MADRID 200000 0 AGENTES COMERCIALES/REPRESENTANTES
18130 CONSTRUCCIÓN Trigueros ANDALUCÍA ESO, EGB, Graduado Escolar 2018-09-14 COMPLETA HUELVA 0 0 TECNICOS EN CONSTRUCCION
18389 INFORMÁTICA/TELECOMUNICACIONES Leganés MADRID Otras Formaciones 2018-09-13 COMPLETA MADRID 0 0 TELECOMUNICACIONES
18682 INGENIERÍA/CALIDAD/CIENCIAS Telde ISLAS CANARIAS Diplomado o Ingeniero Técnico 2018-09-12 COMPLETA PALMAS (LAS) 0 0 OTRAS ACTIVIDADES TÉCNICAS
18684 CONDUCTORES/TRANSPORTE Estepona ANDALUCÍA Estudios primarios 2018-09-12 INDIFERENTE MÁLAGA 0 0 TRANSPORTE DE PERSONAS O MERCANCIAS
19036 ELECTRICIDAD/ELECTRÓNICA/ENERGÍA Las Navas de la Concepción ANDALUCÍA Sin especificar 2018-09-10 COMPLETA SEVILLA 3000 0 ELECTRICIDAD
19465 CONSTRUCCIÓN Porto do Son GALICIA Sin especificar 2018-09-06 COMPLETA CORUÑA (A) 0 0 GRÚAS/EXCAVADORAS/MAQUINARIA
19472 CONDUCTORES/TRANSPORTE Boiro GALICIA Sin especificar 2018-09-06 COMPLETA CORUÑA (A) 0 0 TRANSPORTE DE PERSONAS O MERCANCIAS
19491 CONSTRUCCIÓN Linares ANDALUCÍA Sin especificar 2018-09-06 COMPLETA JAÉN 1250 0 PEONES
19644 PELUQUERÍA/ESTÉTICA Olías del Rey CASTILLA LA MANCHA Sin especificar 2018-09-05 PARCIAL TOLEDO 0 0 PELUQUERÍA
19649 PELUQUERÍA/ESTÉTICA Olías del Rey CASTILLA LA MANCHA Sin especificar 2018-09-05 PARCIAL TOLEDO 0 0 ESTÉTICA
19659 AGRICULTURA/JARDINERÍA/ALIMENTACIÓN Silleda GALICIA Sin especificar 2018-09-05 PARCIAL PONTEVEDRA 0 0 CARNICERÍA/CHARCUTERIA
19797 FÁBRICAS/INDUSTRIA San Sebastián de los Reyes MADRID Sin especificar 2018-09-04 COMPLETA MADRID 0 0 ARTESANÍA/OFICIOS
19806 VIGILANCIA/SERVICIOS Gozón PRINCIPADO DE ASTURIAS Certificados de Profesionalidad 2018-09-04 INDIFERENTE ASTURIAS 0 0 AUXILIARES DE SERVICIO/PERSONAL SUBALTER
20058 CONSTRUCCIÓN Silleda GALICIA Estudios primarios 2018-09-03 COMPLETA PONTEVEDRA 1000 0 PEONES
20077 CONSTRUCCIÓN Silleda GALICIA ESO, EGB, Graduado Escolar 2018-09-03 COMPLETA PONTEVEDRA 1000 0 ALBAÑILERIA/ACABADOS
20401 PELUQUERÍA/ESTÉTICA Avilés PRINCIPADO DE ASTURIAS Certificados de Profesionalidad 2018-05-09 PARCIAL ASTURIAS 4 0 ESTÉTICA
20418 COMUNICACIÓN/CULTURA/ENTRETENIMIENTO Petrer COMUNIDAD VALENCIANA Sin especificar 2018-08-30 COMPLETA ALICANTE 15000 0 APUESTAS Y JUEGO
20420 CUIDADOS/ASISTENCIA EN EL HOGAR Sevilla ANDALUCÍA Sin especificar 2018-08-30 INDIFERENTE SEVILLA 850 0 LIMPIEZA
20582 PELUQUERÍA/ESTÉTICA Salamanca CASTILLA Y LEÓN Licenciado o Ingeniero Superior 2018-08-29 PARCIAL SALAMANCA 1200 0 ESTÉTICA
21013 ELECTRICIDAD/ELECTRÓNICA/ENERGÍA Ourense GALICIA FP I, Ciclo de Grado Medio 2018-08-28 COMPLETA OURENSE 0 0 ELECTRICIDAD
21210 COMUNICACIÓN/CULTURA/ENTRETENIMIENTO Madrid MADRID Sin especificar 2018-08-27 COMPLETA MADRID 0 0 COMUNICACIÓN/PUBLICIDAD/MARKETING
21974 CONSTRUCCIÓN Porto do Son GALICIA Sin especificar 2018-09-06 COMPLETA CORUÑA (A) 0 0 GRÚAS/EXCAVADORAS/MAQUINARIA
22139 CONSTRUCCIÓN Porto do Son GALICIA Sin especificar 2018-09-06 COMPLETA CORUÑA (A) 0 0 GRÚAS/EXCAVADORAS/MAQUINARIA
22146 CONDUCTORES/TRANSPORTE Boiro GALICIA Sin especificar 2018-09-06 COMPLETA CORUÑA (A) 0 0 TRANSPORTE DE PERSONAS O MERCANCIAS
22164 CONSTRUCCIÓN Linares ANDALUCÍA Sin especificar 2018-09-06 COMPLETA JAÉN 1250 0 PEONES
22341 PELUQUERÍA/ESTÉTICA Olías del Rey CASTILLA LA MANCHA Sin especificar 2018-09-05 PARCIAL TOLEDO 0 0 PELUQUERÍA
22346 PELUQUERÍA/ESTÉTICA Olías del Rey CASTILLA LA MANCHA Sin especificar 2018-09-05 PARCIAL TOLEDO 0 0 ESTÉTICA
22356 AGRICULTURA/JARDINERÍA/ALIMENTACIÓN Silleda GALICIA Sin especificar 2018-09-05 PARCIAL PONTEVEDRA 0 0 CARNICERÍA/CHARCUTERIA
22521 FÁBRICAS/INDUSTRIA San Sebastián de los Reyes MADRID Sin especificar 2018-09-04 COMPLETA MADRID 0 0 ARTESANÍA/OFICIOS
22530 VIGILANCIA/SERVICIOS Gozón PRINCIPADO DE ASTURIAS Certificados de Profesionalidad 2018-09-04 INDIFERENTE ASTURIAS 0 0 AUXILIARES DE SERVICIO/PERSONAL SUBALTER
22819 CONSTRUCCIÓN Silleda GALICIA Estudios primarios 2018-09-03 COMPLETA PONTEVEDRA 1000 0 PEONES
22838 CONSTRUCCIÓN Silleda GALICIA ESO, EGB, Graduado Escolar 2018-09-03 COMPLETA PONTEVEDRA 1000 0 ALBAÑILERIA/ACABADOS
23440 PELUQUERÍA/ESTÉTICA Avilés PRINCIPADO DE ASTURIAS Certificados de Profesionalidad 2018-05-09 PARCIAL ASTURIAS 4 0 ESTÉTICA
23457 COMUNICACIÓN/CULTURA/ENTRETENIMIENTO Petrer COMUNIDAD VALENCIANA Sin especificar 2018-08-30 COMPLETA ALICANTE 15000 0 APUESTAS Y JUEGO
23459 CUIDADOS/ASISTENCIA EN EL HOGAR Sevilla ANDALUCÍA Sin especificar 2018-08-30 INDIFERENTE SEVILLA 850 0 LIMPIEZA
23637 PELUQUERÍA/ESTÉTICA Salamanca CASTILLA Y LEÓN Licenciado o Ingeniero Superior 2018-08-29 PARCIAL SALAMANCA 1200 0 ESTÉTICA
24088 ELECTRICIDAD/ELECTRÓNICA/ENERGÍA Ourense GALICIA FP I, Ciclo de Grado Medio 2018-08-28 COMPLETA OURENSE 0 0 ELECTRICIDAD
24296 COMUNICACIÓN/CULTURA/ENTRETENIMIENTO Madrid MADRID Sin especificar 2018-08-27 COMPLETA MADRID 0 0 COMUNICACIÓN/PUBLICIDAD/MARKETING
25399 COMERCIAL/VENTAS Santander CANTABRIA Sin especificar 2018-08-17 PARCIAL CANTABRIA 0 0 VENDEDORES
25517 EDUCACIÓN/SERVICIOS SOCIALES El Astillero CANTABRIA Diplomado o Ingeniero Técnico 2018-08-16 PARCIAL CANTABRIA 0 0 ENSEÑANZA DE IDIOMAS
26002 ADMINISTRACIÓN Barcelona CATALUÑA Sin especificar 2018-08-08 COMPLETA BARCELONA 15000 0 ADMINISTRATIVOS
26003 ADMINISTRACIÓN Barcelona CATALUÑA Sin especificar 2018-08-08 COMPLETA BARCELONA 15000 0 ADMINISTRATIVOS
26626 SALUD/DEPORTE El Pedernoso CASTILLA LA MANCHA Diplomado o Ingeniero Técnico 2018-08-03 PARCIAL CUENCA 0 0 ENFERMERÍA
26702 ELECTRICIDAD/ELECTRÓNICA/ENERGÍA Valladolid CASTILLA Y LEÓN FP I, Ciclo de Grado Medio 2018-08-02 COMPLETA VALLADOLID 20000 0 ELECTRICIDAD
26785 VIGILANCIA/SERVICIOS Madrid MADRID Sin especificar 2018-07-30 COMPLETA MADRID 1200 0 AUXILIARES DE SERVICIO/PERSONAL SUBALTER
26786 FÁBRICAS/INDUSTRIA Argentona CATALUÑA Sin especificar 2018-06-18 COMPLETA BARCELONA 0 0 TEXTIL/CONFECCIÓN/CALZADO
30052 COMERCIAL/VENTAS Valencia COMUNIDAD VALENCIANA ESO, EGB, Graduado Escolar 2018-07-04 INDIFERENTE VALENCIA 2000 0 AGENTES COMERCIALES/REPRESENTANTES
30299 FÁBRICAS/INDUSTRIA Madrid MADRID Certificados de Profesionalidad 2017-06-06 INDIFERENTE MADRID 0 0 FUNDICIÓN/SIDERURGÍA
30301 FÁBRICAS/INDUSTRIA Madrid MADRID Certificados de Profesionalidad 2017-06-06 INDIFERENTE MADRID 0 0 FUNDICIÓN/SIDERURGÍA
32763 CONSTRUCCIÓN Madrid MADRID Licenciado o Ingeniero Superior 2018-06-04 INDIFERENTE MADRID 0 0 TECNICOS EN CONSTRUCCION
offers_sp <- subset(offers_sp, !(SalarioMax==9999999))
offers_sp$SalarioMin <- as.numeric(offers_sp$SalarioMin)
offers_sp$SalarioMax <- as.numeric(offers_sp$SalarioMax)
boxplot(offers_sp$SalarioMax ~ offers_sp$Comunidad)

Veiem que els valors extrems que tenim ara son més raonables, i considero que els podriem deixar tal qual.

boxplot(offers_sp$SalarioMax ~ offers_sp$Categoria)

4. Anàlisi de les dades

Selecció dels grups de dades que es volen analitzar/comparar (planificació dels anàlisis a aplicar)

TODO: Agrupar por comunidad

Comprovació de la normalitat i homogeneïtat de la variància.

Començem mirant si les variables pertanyen a una distribució normal.

p_val_sal_min <- shapiro.test(subset(offers_sp, Comunidad == c("MADRID"))$SalarioMin)$p.value
#p_val_sal_max <- shapiro.test(offers_sp$SalarioMax)$p.value
sprintf("P value para SalarioMin: %f", p_val_sal_min)
[1] "P value para SalarioMin: 0.000000"
#sprintf("P Value para SalarioMax: %d", p_val_sal_max)
hist(subset(offers_sp, Comunidad == c("MADRID"))$SalarioMin)

hist(subset(offers_sp, Comunidad == c("CATALUÑA"))$SalarioMin)

Aplicació de proves estadístiques per comparar els grups de dades. En funció de les dades de l’objectiu de l’estudi, aplicar proves de contrast d’hipòtesi, correlacions, regressions, etc.

cor_matrix <- cor(offers_sp$SalarioMin, offers_sp$SalarioMax)
round(cor_matrix, 2)
[1] 0.63
plotcorr(cor_matrix, mar = c(0.1, 0.1, 0.1, 0.1))
Error in plotcorr(cor_matrix, mar = c(0.1, 0.1, 0.1, 0.1)) : 
  Need a correlation matrix

En aquest punt, ens adonem que hi ha un tipus de registres en els quals tenim 0 a salari minim i máxim, lo que vol dir que aquestes ofertes no han introduit un valor real en quant als salaris, o bé son ofertes de pràctiques no remunerades. Ninguna d’aquestes opcions les volem contemplar en el nostre estudi, així que com tenim dades suficients, podem prescindir d’aquestes.

subset(offers_sp, !(SalarioMin == 0 & SalarioMax == 0))

TODO: En comptes d’utilitzar KNN utilitzar les mitjanes poblacionals per categoria TODO: Hi ha valors de salari Min i Max que s’han d’intercanviar.

5. Representació dels resultats a partir de taules i gràfiques.

6. Resolució del problema. A partir dels resultats obtinguts, quines són les conclusions? Els resultats permeten respondre al problema?

7. Codi: Cal adjuntar el codi

LS0tCnRpdGxlOiAiQ2xlYW5pbmcgU3BhbmlzaCBKb2IgTWFya2V0IERhdGFzZXQiCmF1dGhvcjogIkFudG9uaW8gTWlsw6FuIE90ZXJvIgpkYXRlOiAiRGVjZW1iZXIgMTUsIDIwMTgiCm91dHB1dDoKICBodG1sX2RvY3VtZW50OgogICAgdG9jOiB5ZXMKICBwZGZfZG9jdW1lbnQ6CiAgICB0b2M6IHllcwogIGh0bWxfbm90ZWJvb2s6IAogICAgdG9jOiB5ZXMKLS0tCgpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFKQpgYGAKCmBgYHtyIGxvYWRfbGlicmFyaWVzLCBpbmNsdWRlPUZBTFNFfQpsaWJyYXJ5KGtuaXRyKQpsaWJyYXJ5KGx1YnJpZGF0ZSkKbGlicmFyeShWSU0pCmxpYnJhcnkoc3RyaW5ncikKbGlicmFyeShwc3ljaCkKbGlicmFyeShnZ3Bsb3QyKQojIGZvciBwbG90aW5nIGNvcnJlbGF0aW9ucwpsaWJyYXJ5KGVsbGlwc2UpCmBgYAoKIyMgMS4gRGVzY3JpcGNpw7MgZGVsIGRhdGFzZXQKCkFxdWVzdCBkYXRhc2V0IHByb3bDqSBkZSBsYSBwcsOgY3RpY2EgYW50ZXJpb3IsIGVuIGxhIHF1YWwsIG5vIHZhaWcgcHJlc3RhciBnZW5zIGQnYXRlbmNpw7MgYSBsYSBuZXRlamEgZGUgbGVzIGRhZGVzLCBkb25hbnQgY29tIGEgcmVzdWx0YXQgdW4gZGF0YXNldCBtb2x0IGJydXQuIEFpeMOyIGVzIHZhIGZlciBhIHByb3Bvc2l0IHBlciB0YWwgZGUgcG9kZXIgYXByb2ZpdGFyIGFxdWVzdCBkYXRhc2V0IGVuIGFxdWVzdGEgcHLDoGN0aWNhLgoKQXF1ZXN0IGRhdGFzZXQgY29udMOpIGluZm9ybWFjacOzIHNvYnJlIG9mZXJ0ZXMgbGFib3JhbHMgdHJvYmFkZXMgYSBsYSB3ZWIgcHJvcG9yY2lvbmFkYSBwZXIgbCdlc3RhdCBFc3BhbnlvbCBwZXIgYSB0YWwgcHJvcG9zaXQuCgpMYSBwcmVndW50YSBxdWUgdm9sZW0gcmVzcG9uZHJlIGFtYiBhcXVlc3QgZGF0YXNldCBzZXLDoDoKCi0gUXVpbmVzIHJlZ2lvbnMgZCdFc3BhbnlhIGdlbmVyZW4gbcOpcyBvZmVydGVzIGRlIHRyZWJhbGw/Ci0gUXVpbiB0aXB1cyBkZSBwcm9mZXNzaW9uYWwgZXMgZWwgbcOpcyBzb2xpY2l0YXQgYSBFc3BhbnlhIChkdXJhbnQgZWwgcGVyaW9kZSBkZSBtb3N0cmVpZyk/Ci0gRXN0dWRpIHNvYnJlIGVscyBzYWxhcmlzIGVuIHJlbGFjacOzIGEgbGVzIHJlZ2lvbnMuIEEgb24gdHJvYmVtIHVuIG1ham9yIHNhbGFyaT8KCkEgbGEgcHLDoGN0aWNhIGFudGVyaW9yIGVudW1lcmFiZW0gdGFtYsOpIGxlcyBzZWfDvGVudHMgaWRlZXM6CgotIEFuYWxpdHphciBlbHMgZGlmZXJlbnRzIHJlcXVlcmltZW50cyBwcm9mZXNzaW9uYWxzIHF1ZSB0ZW5lbiBsZXMgZGlmZXJlbnRzIGF1dG9ub21pZXMgZCdFc3BhbnlhLgotIElkZW50aWZpY2FyIGVsIHRpcHVzIGkgbGEgcXVhbGl0YXQgZGVsIHRyZWJhbGwgYWN0dWFsIGFsIHBhw61zLgotIEFuYWxpdHphciBsZXMgcmVnaW9ucyBhbWIgbcOpcyBpIG1lbnlzIG9mZXJ0ZXMgZGUgdHJlYmFsbC4KLSBBbmFsaXR6YXIgbGEgZGlzdHJpYnVjacOzIGRlIGxlcyBkaWZlcmVudHMgcHJvZmVzc2lvbnMgZW4gZnVuY2nDsyBkZSBsYSByZWdpw7MuCi0gQWp1ZGFyIGEgbGEgY3JlYWNpw7MgZOKAmXVuIHBsYSBwZXIgcG90ZW5jaWFyIGVsIG1lcmNhdCBsYWJvcmFsIGJhc2F0IGVuIGVsIGNvbmVpeGVtZW50IG9idGluZ3V0IGEgdHJhdsOpcyBkZSBsZXMgZGFkZXMuCgpQZXLDsiBhcXVlc3RlcyBsZXMgZGVpeGFyZW0gcGVyIGZ1dHVycyB0cmViYWxscy4KCiMjIDIuIEludGVncmFjacOzIGkgc2VsZWNjacOzIGRlIGxlcyBkYWRlcyBkJ2ludGVyw6hzIGEgYW5hbGl0emFyCgpQZXIgYXF1ZXN0IGFwYXJ0YXQgamEgZXMgdmEgY3JlYXIgdW4gc2NyaXB0IHB5dGhvbiBxdWUgcydlbmNhcnJlZ2FiYSBkJ2FqdW50YXIgbGVzIGRhZGVzIG9idGluZ3VkZXMgZW4gZGlmZXJlbnRzIGRpZXMuIExhIGlkZWEgZGFycmVyYSBkJ2FxdWVzdCBzY3JpcHQgZXJhIGxhIGRlIHJlY29sZWN0YXIgdG90ZXMgbGVzIGRhZGVzIGRpc3BvbmlibGVzIGEgbGEgd2ViIGVuIHVuYSBwcmltZXJhIHBhc2FkYSwgaSBkZXNwcsOocyBhbmFyIGFjdHVhbGl0emFudCBlbCBkYXRhc2V0IGFnYWZhbnQgZGFkZXMgZGlhcmllcyBpIGFncnVwYW50LWxlcyBzb3RhIGVsIG1hdGVpeCBmaXR4ZXIgLmNzdgoKUGVyIHRhbnQsIGVuIGFxdWVzdCBhcGFydGF0IGNvbnNpZGVybyBxdWUgbm8gaGFpZyBkZSBmZXIgbcOpcyBxdWUgZWwgamEgZmV0IGZpbnMgYSBsYSBkYXRhLgoKRWwgc2NyaXB0IGVzIHBvdCB0cm9iYXIgZW4gbGEgc2Vnw7xlbnQgVVJMOgpbaHR0cHM6Ly9naXRodWIuY29tL2FtaWxhbi9zcGFuaXNoX2pvYl9tYXJrZXQvYmxvYi9tYXN0ZXIvc3JjL2RhdGFzZXRfbWVyZ2UucHldCgpUYW1iw6kgdGluYyBlbiBjb21wdGUsIHF1ZSBsYSB3ZWIgb2ZpY2lhbCBkZSBsYSBxdWFsIGVzIHZhIGV4dHJldXJlIGxlcyBkYWRlcywgamEgcmVjb3BpbGEgYXF1ZXN0ZXMgZGFkZXMgZGUgZGlmZXJlbnQgZm9udHMsIGFpeMOtIGRvbmNzLCBubyBjb25zaWRlcm8gcXVlIHNpZ3VpIG5lY2Vzc2FyaSBsJ2ludGVncmFjacOzIGRlIGRhZGVzIGRlIGRpZmVyZW50ZXMgZm9udHMsIGphIHF1ZSBhcXVlc3RhIGhhIGVzdGF0IHJlYWxpdHphZGEgYW50ZXJpb3JtZW50LgoKPiBIYXVyaWEgZCdleHBsaWNhciB1bmEgbWljYSBjb20gZmFyaWEgYXF1ZXN0YSBpbnRlZ3JhY2nDsyBlbiBjYXMgZGUgcXVlIG5vIGhhZ3XDqXMgZXN0YXQgZmV0YSBwZXIgbGEgcHJvcGlhIGZvbnQgdXRpbGl0emFkYT8KPiBSZXZpc2FyIHNpIHMnaGEgZCdleHBhbmRpciBtw6lzIGFxdWVzdGEgZXhwbGljYWNpw7Mgc29icmUgbGEgaW50ZWdyYWNpw7MgaSBzZWxlY2Npw7MgZGUgZGFkZXMgZCdpbnRlcsOocwoKRW4gYXF1ZXN0IGFwYXJ0YXQgc2VsZWNjaW9uYXJlbSBsZXMgZGFkZXMgbmVjZXNzYXJpZXMgcGVyIGFscyBub3N0cmVzIGVzdHVkaXMuCkhlbSBkZSB0ZW5pciBlbiBjb21wdGUsIHF1ZSBhIGxhIHByw6BjdGljYSBhbnRlcmlvciBoZW0gdmFpZyBsaW1pdGFyIGEgYWdhZmFyIHRvdGVzIGxlcyBkYWRlcyBwb3NzaWJsZXMgaSBhIHBvc3Nhci1sZXMgZW4gdW4gZml0eGVyIC5jc3YuCkFxdWVzdGVzIGRhZGVzIHByb3ZlbmllbiBkJ3VuYSBiYXNlIGRlIGRhZGVzIE5vU1FMLCBqYSBxdWUgdmFpZyBkZXRlY3RhciBxdWUgYW1iIGxlcyBtYXRlaXhlcyBjcmlkZXMsIHBvZGllbSBvYnRlbmlyIGRhZGVzIGFtYiBkaWZlcmVudHMgZXNxdWVtZXMgKHNjaGVtYWxlc3MpLiBBaXjDrSBkb25jcywgZmFyZW0gdW5hIHNlbGVjY2nDsyBkZSBsZXMgZGFkZXMgcXVlIHV0aWxpdHphcmVtIGkgZWxpbWluYXJlbSBhaXjDrSBkYWRlcyBubyBuZWNlc3PDoHJpZXMgbyByZXBldGlkZXMuCgpDb21lbsOnZW0gY2FycmVnYW50IGxlcyBkYWRlczoKCmBgYHtyfQpvZmZlcnMgPC0gcmVhZC5jc3YoIi4vZGF0YS9vZmZlcnNfZGF0YXNldC5jc3YiKQpoZWFkKG9mZmVycykKYGBgCgpgYGB7cn0KbGVuZ3RoKG9mZmVycyRjYXRlZ29yaWEpCmBgYAoKQ29tIHBvZGVtIHZldXJlLCB0ZW5pbSA0MDUzNCByZWdpc3RyZXMgaSA5NCBjYXJhY3RlcsOtc3RpcXVlcywgbW9sdGVzIGRlIGxlcyBxdWFscyBubyBlbnMgc2Vyw6BuIGQndXRpbGl0YXQuCgpgYGB7cn0KbmFtZXMob2ZmZXJzKQpgYGAKCkFpeMOtIGRvbmNzLCBjb21lbsOnYXJlbSBzZWxlY2Npb25hbnQgbGVzIGRhZGVzIGQnaW50ZXLDqXMuIFJlY29yZGVtIHF1ZSBsYSBtZXZhIGludGVuY2nDsyBlcyBsYSBkZSBmZXIgdW4gZXN0dWRpIHNvYnJlIGVscyB0aXB1cyBkJ29mZXJ0ZXMgZGUgdHJlYmFsbHMgYSBFc3BhbnlhIGkgZW4gY29uY3JldCBhIGNhZGFzY3VuYSBkZSBsZXMgcmVnaW9ucy4KClByaW1lcmFtZW50LCBjb21wcm92YXJlbSBxdWUgbm9tw6lzIHRlbmltIGRhZGVzIGQnb2ZlcnRlcyByZWFsaXR6YWRlcyBhIEVzcGFueWEuCgpgYGB7cn0KbGV2ZWxzKG9mZmVycyRwYWlzUykKYGBgCgpDb21wcm92ZW0gZHVlcyBjb3NlcywgcXVlIHRlbmltIG9mZXJ0ZXMgZCdFc3BhbnlhIGkgdGFtYsOpIGFsIENvbmdvLCBpIHF1ZSB0ZW5pbSB1biBwcm9ibGVtYSBkZSBjb2RpZmljYWNpw7MgZGUgY2FyYWN0ZXJzLCBqYSBxdWUgZW5zIHRyb2JhIGVsIHBhw61zIGQnRXNwYW55YSBlbiB0cmVzIGZhY3RvcnMgZGlmZXJlbnRzLiBDb20gcXVlIG5vbcOpcyB2b2xlbSB1dGlsaXR6YXIgbGVzIGRhZGVzIGRlIGxlcyBvZmVydGVzIGEgRXNwYW55YSwgcG9kZW0gc2VsZWNjaW9uYXIgdG90ZXMgbGVzIHF1ZSBubyBzaWd1aW4gYWwgQ29uZ28gaSBkZXNwcsOocyBlbGltaW5hciBhcXVlc3RhIGNvbHVtbmEuCgpQb2RlbSBjb3JyZWdpciBsZXMgZGFkZXMgZXJyb25lZXMgZGUgcGHDrXM6CgpgYGB7cn0Kb2ZmZXJzJHBhaXNTIDwtIHN1YigiRVNQQcOD4oCYQSIsICJFU1BBw5FBIiwgb2ZmZXJzJHBhaXNTKQpvZmZlcnMkcGFpc1MgPC0gc3ViKCJFU1BB77+977+9QSIsICJFU1BBw5FBIiwgb2ZmZXJzJHBhaXNTKQpsZXZlbHMoZmFjdG9yKG9mZmVycyRwYWlzUykpCmBgYAoKVGFtYsOpIHBvZHJpZW0gaGF2ZXIgY2FudmlhdCBsYSBjb2RpZmljYWNpw7MgZGVscyBjYXJhY3RlcnMsIGNvbSB2ZXVyZW0gbcOpcyBlbmRhdmFudC4KClNlbGVjY2lvbmVtIGFyYSBub23DqXMgbGVzIG9mZXJ0ZXMgYSBFc3BhbnlhLgoKYGBge3J9CiNvZmZlcnNfc3AgPC0gc3Vic2V0KG9mZmVycywgIShwYWlzUyAlaW4lIGMoIkNPTkdPIikpCiNvZmZlcnNfc3AgPC0gc3Vic2V0KG9mZmVycywgIShwYWlzUyA9PSAiQ09OR08iKSkKb2ZmZXJzIDwtIHN1YnNldChvZmZlcnMsIHBhaXNTID09ICJFU1BBw5FBIikKbGV2ZWxzKGZhY3RvcihvZmZlcnMkcGFpc1MpKQojIHBhaXNTIGVzIGFyYSBkZWwgdGlwdXMgY2hyLCBoYXVyaWVtIGRlIGNvbnZlcnRpcmxhIGRlIG5vdSBhIGZhY3RvcgpvZmZlcnMkcGFpc1MgPC0gZmFjdG9yKG9mZmVycyRwYWlzUykKYGBgCmBgYHtyfQpjbGFzcyhvZmZlcnMkcGFpc1MpCmBgYAoKU2VndWlkYW1lbnQsIGVsaW1pbmFyZW0gbGVzIGNvbHVtbW5lcyBxdWUgb2ZlcmVpeGVuIGluZm9ybWFjacOzIGR1cGxpY2FkYS4gRW5zIHF1ZWRhcmVtIGFtYiBsZXMgY2FyYWN0ZXLDrXN0aXF1ZXM6CgotIGNhdGVnb3JpYUYKLSBjaXVkYWRGCi0gY29tdW5pZGFkRgotIGVkdWNhY2lvbkYKLSBmZWNoYUNyZWFjaW9uCi0gam9ybmFkYUYKLSBwYWlzUwotIHByb3ZpbmNpYVMKLSBzYWxhcmlvTWF4Ci0gc2FsYXJpb01pbgotIHN1YmNhdGVnb3JpYVMKCmBgYHtyfQpzZWxlY3RlZF9mZWF0dXJlcyA8LSBjKCJjYXRlZ29yaWFGIiwgImNpdWRhZEYiLCAiY29tdW5pZGFkRiIsICJlZHVjYWNpb25GIiwgImZlY2hhQ3JlYWNpb24iLCAiam9ybmFkYUYiLCAicGFpc1MiLCAicHJvdmluY2lhUyIsICJzYWxhcmlvTWF4IiwgInNhbGFyaW9NaW4iLCAic3ViY2F0ZWdvcmlhUyIpCm9mZmVycyA8LSBvZmZlcnNbc2VsZWN0ZWRfZmVhdHVyZXNdCmhlYWQob2ZmZXJzKQpgYGAKCiMgMy4gTmV0ZWphIGRlIGxlcyBkYWRlcwoKIyMgTGVzIGRhZGVzIGNvbnRlbmVuIHplcm9zIG8gZWxlbWVudHMgYnVpdHM/IENvbSBnZXN0aW9uYXJpZXMgYXF1ZXN0cyBjYXNvcz8KCmBgYHtyfQpzYXBwbHkob2ZmZXJzLCBmdW5jdGlvbih4KShzdW0oaXMubmEoeCkpKSkKYGBgCgpgYGB7cn0KbGVuZ3RoKG9mZmVycyRzYWxhcmlvTWF4KQpgYGAKCmBgYHtyfQpsZXZlbHMob2ZmZXJzJGNvbXVuaWRhZEYpCmBgYAoKYGBge3J9Cm9mZmVycyRjb211bmlkYWRGIDwtIHN1YigiQVJBR8OD4oCcTiIsICJBUkFHw5NOIiwgb2ZmZXJzJGNvbXVuaWRhZEYpCm9mZmVycyRjb211bmlkYWRGIDwtIHN1YigiQ0FTVElMTEEgWSBMRe+/ve+/vU4iLCAiQ0FTVElMTEEgWSBMRcOTTiIsIG9mZmVycyRjb211bmlkYWRGKQpvZmZlcnMkY29tdW5pZGFkRiA8LSBzdWIoIkNBU1RJTExBIFkgTEXDg+KAnE4iLCAiQ0FTVElMTEEgWSBMRcOTTiIsIG9mZmVycyRjb211bmlkYWRGKQpvZmZlcnMkY29tdW5pZGFkRiA8LSBzdWIoIkNBVEFMVe+/ve+/vUEiLCAiQ0FUQUxVw5FBIiwgb2ZmZXJzJGNvbXVuaWRhZEYpCm9mZmVycyRjb211bmlkYWRGIDwtIHN1YigiQ0FUQUxVw4PigJhBIiwgIkNBVEFMVcORQSIsIG9mZmVycyRjb211bmlkYWRGKQpvZmZlcnMkY29tdW5pZGFkRiA8LSBzdWIoIkFOREFMVUPDg++/vUEiLCAiQU5EQUxVQ8ONQSIsIG9mZmVycyRjb211bmlkYWRGKQpvZmZlcnMkY29tdW5pZGFkRiA8LSBzdWIoIlJFR0nvv73vv71OIERFIE1VUkNJQSIsICJSRUdJw5NOIERFIE1VUkNJQSIsIG9mZmVycyRjb211bmlkYWRGKQpvZmZlcnMkY29tdW5pZGFkRiA8LSBzdWIoIlJFR0nDg+KAnE4gREUgTVVSQ0lBIiwgIlJFR0nDk04gREUgTVVSQ0lBIiwgb2ZmZXJzJGNvbXVuaWRhZEYpCm9mZmVycyRjb211bmlkYWRGIDwtIHN1YigiUEHDg++/vVMgVkFTQ08iLCAiUEHDjVMgVkFTQ08iLCBvZmZlcnMkY29tdW5pZGFkRikKIyBvZmZlcnMkY29tdW5pZGFkRiA8LSBzdWIoIlNpbiBlc3BlY2lmaWNhciIsICIiLCBvZmZlcnMkY29tdW5pZGFkRikKb2ZmZXJzJGNvbXVuaWRhZEYgPC0gZmFjdG9yKG9mZmVycyRjb211bmlkYWRGKQpsZXZlbHMob2ZmZXJzJGNvbXVuaWRhZEYpCmBgYAoKVmVpZW0gcXVlIGVuIGFxdWVzdCBjYXMgcG9kZW0gdGVuaXIgdmFsb3IgYnVpdCAoIiIpIG8gX19zaW4gZXNwZWNpZmljYXJfXy4gRW5zIGludGVyZXNzYSBkZWl4YXIgZWxzIGRvcyBjYXNvcywgamEgcXVlIF9fc2luIGVzcGVjaWZpY2FyX18gcG90IHNlciB1bmEgCgo+IFRPRE86IERlc2NyaXVyZSBtaWxsb3IgY29tIHV0aWxpdHphcmVtIGVscyBjYXNvcyBidWl0cy4KCmBgYHtyfQojIG9mZmVyc1t3aGljaChvZmZlcnMkY29tdW5pZGFkRiA9PSAiQ0FUQUxVw5FBIiksXQpsZXZlbHMob2ZmZXJzJGNhdGVnb3JpYUYpCmBgYAoKRW4gY29tcHRlcyBkZSBjb3JyZWdpciB1biBhIHVuLCB0cmFuc2Zvcm1hcmVtIGxlcyBkYWRlcyBhbCBmb3JtYXQgbGF0aW4xLgoKYGBge3J9CiMgY29udmVydGltIGxlcyBkYWRlcyBhIGVuY29kaW5nIGxhdGluMQpvZmZlcnMkY2F0ZWdvcmlhRiA8LSBmYWN0b3IoaWNvbnYob2ZmZXJzJGNhdGVnb3JpYUYsIHRvID0gImxhdGluMSIpKQpsZXZlbHMob2ZmZXJzJGNhdGVnb3JpYUYpCmBgYAo+IFRPRE86ClJldmlzYXIgcHJvdmluY2lhcyEhISBHdWlwdXpjdWEgZXN0YSByZXBldGlkYSEhISEKCmBgYHtyfQojIG9mZmVyc1t3aGljaChvZmZlcnMkY29tdW5pZGFkRiA9PSAiQ0FUQUxVw5FBIiksXQpsZXZlbHMob2ZmZXJzJHByb3ZpbmNpYVMpCmBgYAoKYGBge3J9CiMgb2ZmZXJzW3doaWNoKG9mZmVycyRjb211bmlkYWRGID09ICJDQVRBTFXDkUEiKSxdCmxldmVscyhvZmZlcnMkam9ybmFkYUYpCmBgYAoKYGBge3J9CiMgb2ZmZXJzW3doaWNoKG9mZmVycyRjb211bmlkYWRGID09ICJDQVRBTFXDkUEiKSxdCiMgY29udmVydGltIGxlcyBkYWRlcyBhIGVuY29kaW5nIGxhdGluMQpvZmZlcnMkc3ViY2F0ZWdvcmlhUyA8LSBmYWN0b3IoaWNvbnYob2ZmZXJzJHN1YmNhdGVnb3JpYVMsIHRvID0gImxhdGluMSIpKQpsZXZlbHMob2ZmZXJzJHN1YmNhdGVnb3JpYVMpCmBgYAoKYGBge3J9CiMgb2ZmZXJzW3doaWNoKG9mZmVycyRjb211bmlkYWRGID09ICJDQVRBTFXDkUEiKSxdCiMgY29udmVydGltIGxlcyBkYWRlcyBhIGVuY29kaW5nIGxhdGluMQpvZmZlcnMkZWR1Y2FjaW9uRiA8LSBmYWN0b3IoaWNvbnYob2ZmZXJzJGVkdWNhY2lvbkYsIHRvID0gImxhdGluMSIpKQpsZXZlbHMob2ZmZXJzJGVkdWNhY2lvbkYpCmBgYAoKVG90IGkgbGEgY29udmVyc2nDsywgZW5jYXJhIHRlbmltIGFsZ3VuIGNhcyBxdWUgbm8gcydoYSBjb2RpZmljYXQgY29ycmVjdGFtZW50LiBFbCBjb3JyZWdpcmVtIG1hbnVhbG1lbnQuCgpgYGB7cn0Kb2ZmZXJzJGVkdWNhY2lvbkYgPC0gc3ViKCJEaXBsb21hZG8gbyBJbmdlbmllcm8gVMODwqljbmljbyIsICJEaXBsb21hZG8gbyBJbmdlbmllcm8gVMOpY25pY28iLCBvZmZlcnMkZWR1Y2FjaW9uRikKb2ZmZXJzJGVkdWNhY2lvbkYgPC0gZmFjdG9yKG9mZmVycyRlZHVjYWNpb25GKQpsZXZlbHMob2ZmZXJzJGVkdWNhY2lvbkYpCmBgYAoKUGFzc2VtIGFyYSBhIG5ldGVqYXIgbGVzIGNhcmFjdGVyw61zdGlxdWVzIG51bcOpcmlxdWVzLiBWZWllbSBxdWUgYXByb3hpbWFkYW1lbnQgdW5hIHF1YXJ0YSBwYXJ0IGRlIGxlcyBkYWRlcyBkaXNwb3NzZW4gZGUgdmFsb3JzIGRlIHNhbGFyaSBtw61uaW0gaSBtw6F4aW0uIEFxdWVzdHMgZW5zIHBvZHJpZW4gc2VyIHN1ZmljaWVudCBwZXIgYWwgbm9zdHJlcyBlc3R1ZGksIHNlbXByZSBpIHF1YW4gdGluZ3VlbSBzdWZpY2llbnQgY2Fzb3MgZCdlc3R1ZGkgcGVyIGEgbGVzIGRpZmVyZW50ZXMgcmVnaW9ucy4KCkxsYXZvcnMsIGVucyBxdWVkYXJlbSBhbWIgbGVzIGRhZGVzIHF1ZSB0ZW5lbiB1biBzYWxhcmkgbcOtbmltIGkgZGVzY2FydGFyZW0gbGEgcmVzdGEuIENvbSBxdWUgaGkgaGEgbWVueXMgZGFkZXMgYW1iIHNhbGFyaSBtw6F4aW0sIGFxdWVzdCBsJ2ltcHV0YXJlbSB1dGlsaXR6YW50IGtubi4KCmBgYHtyfQpvZmZlcnNfc3AgPC0gc3Vic2V0KG9mZmVycywgIWlzLm5hKG9mZmVycyRzYWxhcmlvTWluKSkKYGBgCgpgYGB7cn0Kc2FwcGx5KG9mZmVyc19zcCwgZnVuY3Rpb24oeCkoc3VtKGlzLm5hKHgpKSkpCmBgYAoKYGBge3J9Cm9mZmVyc19zcCRzYWxhcmlvTWF4IDwtIGtOTihvZmZlcnNfc3ApJHNhbGFyaW9NYXgKc2FwcGx5KG9mZmVyc19zcCwgZnVuY3Rpb24oeCkoc3VtKGlzLm5hKHgpKSkpCmBgYAoKQXJhIG5vbcOpcyBlbnMgcXVlZGVuIHBlciB0cmFjdGFyIDQgY2Fzb3MgZGUgY2F0ZWdvcmlhRiBpIDIgZGUgc3ViY2F0ZWdvcmlhUy4KCmBgYHtyfQprYWJsZShzdWJzZXQob2ZmZXJzX3NwLCBpcy5uYShvZmZlcnNfc3AkY2F0ZWdvcmlhRikpKQpgYGAKCk1pcmFudCBsYSBzdWJjYXRlZ29yaWEsIHZlaWVtIGNsYXJhbWVudCBxdWUgbGVzIGR1ZXMgw7psdGltZXMgcGVydGFueWVuIGEgbGEgY2F0ZWdvcmlhOiBJTkZPUk3DgVRJQ0EvVEVMRUNPTVVOSUNBQ0lPTkVTLCBwZXLDsiBtYWxhdXJhZGFtZW50LCBsZXMgZHVlcyBwcmltZXJlcyBubyB0ZW5lbiBzdWJjYXRlZ29yaWEuIEFpeMOtIGRvbmNzLCBkZXNjYXJ0YXJlbSBsZXMgZHVlcyBwcmltZXJlcyBpIGVucyBxdWVkYXJlbSBhbWIgbGVzIGR1ZXMgw7psdGltZXMsIGludHJvZHVpbnQgZWwgbm91IHZhbG9yIGEgbGEgY2F0ZWdvcmlhLgoKYGBge3J9Cm9mZmVyc19zcCA8LSBzdWJzZXQob2ZmZXJzX3NwLCAhaXMubmEob2ZmZXJzX3NwJHN1YmNhdGVnb3JpYVMpKQpgYGAKCmBgYHtyfQpzYXBwbHkob2ZmZXJzX3NwLCBmdW5jdGlvbih4KShzdW0oaXMubmEoeCkpKSkKYGBgCgpDb20gcXVlIG5vbcOocyBlbnMgcXVlZGVuIGRvcyB2YWxvcnMgTkEgcGVyIHN1YnN0aXR1aXIgaSBzb24gZWxzIHF1ZSBjb25laXhlbSwgcG9kZW0gZmVyIGxhIHNlZ8O8ZW50IG9wZXJhY2nDsy4KCmBgYHtyfQpvZmZlcnNfc3BbaXMubmEob2ZmZXJzX3NwKV0gPC0gYygiSU5GT1JNw4FUSUNBL1RFTEVDT01VTklDQUNJT05FUyIpCmBgYAoKYGBge3J9CnNhcHBseShvZmZlcnNfc3AsIGZ1bmN0aW9uKHgpKHN1bShpcy5uYSh4KSkpKQpgYGAKCkNvbXByb3ZlbSBxdWUgamEgbm8gdGVuaW0gY2FwIHZhbG9yIE5BLgoKYGBge3J9CnN1bW1hcnkob2ZmZXJzX3NwKQpgYGAKClNlZ3VpZGFtZW50IHBvZHJpZW0gY29tcHJvdmFyIHNpIGxlcyBub3N0cmVzIGRhZGVzIHRlbmVuIGVsIHRpcHVzIHF1ZSBkZXNpdGplbS4KCmBgYHtyfQpzYXBwbHkob2ZmZXJzX3NwLCBmdW5jdGlvbih4KShjbGFzcyh4KSkpCmBgYAoKVmVpZW0gcXVlIGhhdXJlbSBkZSB0cmFjdGFyIGVsIGZvcm1hdCBkZSBsYSBjYXJhY3RlcsOtc3RpY2EgZmVjaGFDcmVhY2lvbi4gRW4gYXF1ZXN0IG1vbWVudCwgdGVuaW0gbGEgZGF0YSBjb20gYSB1biBzdHJpbmcgYW1iIGVsIGZvcm1hdDogYW55cywgbWVzLCBkaWEsIGhvcmEuIEVuIGVsIG5vc3RyZSBjYXMsIG5vbcOocyBhbWIgbCdhbnksIG1lcyBpIGRpYSBlbiB0aW5kcmVtIHByb3UuIEEgbcOpcywgaGF1cmVtIGRlIGRvbmFyLWxpIGVsIHRpcHVzIGRlIGRhdGUgdHlwZS4KCmBgYHtyfQpvZmZlcnNfc3AkZmVjaGFDcmVhY2lvbiA8LSBhcy5EYXRlKGdzdWIoIlRcXGQqOlxcZCo6XFxkKloiLCAiIiwgb2ZmZXJzX3NwJGZlY2hhQ3JlYWNpb24pKQpzYXBwbHkob2ZmZXJzX3NwLCBmdW5jdGlvbih4KShjbGFzcyh4KSkpCmBgYAoKYGBge3J9CnN1bW1hcnkob2ZmZXJzX3NwKQpgYGAKClBlciDDumx0aW0sIHBvZGVtIGNhbnZpYXIgZWwgbm9tYnJlIGRlIGxlcyBjYXJhY3RlcsOtc3RpcXVlcyBwZXIgcXVlIHRpbmd1aW4gdW5hIG1pY2EgbcOpcyBkZSBzZW50aXQgaSBndWFyZGVtIGxlcyBkYWRlcyBlbiB1biBub3UgZml0eGVyIGNzdi4KCmBgYHtyfQpuYW1lcyhvZmZlcnNfc3ApCmBgYAoKYGBge3J9CmZpbmFsX25hbWVzIDwtIGMoIkNhdGVnb3JpYSIsICJDaXVkYWQiLCAiQ29tdW5pZGFkIiwgIkVkdWNhY2lvbiIsICJGZWNoYUNyZWFjaW9uIiwgIlRpcG9Kb3JuYWRhIiwgIlBhaXMiLCAiUHJvdmluY2lhIiwgIlNhbGFyaW9NYXgiLCAiU2FsYXJpb01pbiIsICJTdWJDYXRlZ29yaWEiKQpuYW1lcyhvZmZlcnNfc3ApIDwtIGZpbmFsX25hbWVzCmhlYWQob2ZmZXJzX3NwKQpgYGAKClZlaWVtIHRhbWLDqSBxdWUgamEgbm8gbmVjZXNzaXRlbSBsYSB2YXJpYWJsZSBQYWlzLiBQb2RyaWVtIGVsaW1pbmFyLWxhLgoKYGBge3J9Cm9mZmVyc19zcCRQYWlzIDwtIE5VTEwKI25hbWVzKG9mZmVyc19zcCkKdGFpbChvZmZlcnNfc3ApCmBgYAoKUGVyIMO6bHRpbSwgcG9kcmllbSBleHBvcnRhciBlbCBub3N0cmUgY29uanVudCBkZSBkYWRlcyBuZXRlamF0LgoKYGBge3J9CndyaXRlLmNzdihvZmZlcnNfc3AsICIuL2RhdGEvc3BhbmlzaF9qb2Jfb2ZmZXJzX2NsZWFuLmNzdiIpCmBgYAoKIyMgSWRlbnRpZmljYWNpw7MgaSB0cmFjdGFtZW50IGRlIHZhbG9ycyBleHRyZW1zLgoKRG9uZW0gYXJhIHVuIGNvcCBkJ3VsbCBhIGxlcyBkYWRlcyBwZXIgdGFsIGQnaWRlbnRpZmljYXIgdmFsb3JzIGV4dHJlbXMuCgpgYGB7cn0KYm94cGxvdChvZmZlcnNfc3AkU2FsYXJpb01pbikKYGBgCgpgYGB7cn0KYm94cGxvdChvZmZlcnNfc3AkU2FsYXJpb01heCkKYGBgCgpgYGB7cn0KYm94cGxvdChvZmZlcnNfc3AkU2FsYXJpb01pbiB+IG9mZmVyc19zcCRDb211bmlkYWQpCmBgYAoKYGBge3J9CmJveHBsb3Qob2ZmZXJzX3NwJFNhbGFyaW9NYXggfiBvZmZlcnNfc3AkQ29tdW5pZGFkKQpgYGAKCmBgYHtyfQpib3hwbG90LnN0YXRzKG9mZmVyc19zcCRTYWxhcmlvTWluKSRvdXQKYGBgCgpgYGB7cn0KYm94cGxvdC5zdGF0cyhvZmZlcnNfc3AkU2FsYXJpb01heCkkb3V0CmBgYAoKVmVpZW0gcXVlIHRlbmltIHZhbG9ycyBleHRyZW1zIHRhbnQgZW4gZWxzIHNhbGFyaXMgbcOgeGltcyBjb20gZW4gZWxzIG3DrW5pbXMuIEVuIGVsIGNhcyBkZWxzIHNhbGFyaXMgbcOtbmltcywgc29uIHZhbG9yIHJhb25hYmxlcywgaSBjcmVjIHF1ZSBlbHMgaGF1cmllbSBkZSBkZWl4YXIgdGFsIHF1YWwgc29uLiBFbiBjYW52aSwgdHJvYmVtIGRvcyB2YWxvcnMgZXh0cmVtcyBtb2x0IGN1cmlvc29zLCBxdWUgc2VtYmxlbiBzZXIgYWxndW5hIG1lbmEgZGUgdmFsb3IgcHJlZml4YXQgcGVyIGEgbm8gZG9uYXIgdW4gbMOtbWl0IHN1cGVyaW9yLiBFbiBhcXVlc3QgY2FzLCBqYSBxdWUgc29uIG5vbcOpcyBkb3MgdmFsb3JzIGkgdGVuaW0gc3VmaWNpZW50IGRhZGVzIHBlciBhbCBub3N0cmUgZXN0dWRpLCBjb25zaWRlcm8gcXVlIGxvIG1pbGxvciBzZXLDrWEgdHJldXJlIGxlcyBkYWRlcyBjb3JyZXNwb25lbnRzLiBBaXjDrSBkb25jcywgaG8gZmFyZW0gZGUgbGEgc2Vnw7xlbnQgbWFuZXJhLgoKYGBge3J9CmthYmxlKHN1YnNldChvZmZlcnNfc3AsIFNhbGFyaW9NYXggPT0gOTk5OTk5OSkpCmBgYAoKYGBge3J9CmthYmxlKHN1YnNldChvZmZlcnNfc3AsIFNhbGFyaW9NaW4gPT0gMCkpCmBgYAoKYGBge3J9Cm9mZmVyc19zcCA8LSBzdWJzZXQob2ZmZXJzX3NwLCAhKFNhbGFyaW9NYXg9PTk5OTk5OTkpKQpgYGAKCmBgYHtyfQpvZmZlcnNfc3AkU2FsYXJpb01pbiA8LSBhcy5udW1lcmljKG9mZmVyc19zcCRTYWxhcmlvTWluKQpvZmZlcnNfc3AkU2FsYXJpb01heCA8LSBhcy5udW1lcmljKG9mZmVyc19zcCRTYWxhcmlvTWF4KQpib3hwbG90KG9mZmVyc19zcCRTYWxhcmlvTWF4IH4gb2ZmZXJzX3NwJENvbXVuaWRhZCkKYGBgCgpWZWllbSBxdWUgZWxzIHZhbG9ycyBleHRyZW1zIHF1ZSB0ZW5pbSBhcmEgc29uIG3DqXMgcmFvbmFibGVzLCBpIGNvbnNpZGVybyBxdWUgZWxzIHBvZHJpZW0gZGVpeGFyIHRhbCBxdWFsLgoKYGBge3J9CmJveHBsb3Qob2ZmZXJzX3NwJFNhbGFyaW9NYXggfiBvZmZlcnNfc3AkQ2F0ZWdvcmlhKQpgYGAKCiMgNC4gQW7DoGxpc2kgZGUgbGVzIGRhZGVzCiMjIFNlbGVjY2nDsyBkZWxzIGdydXBzIGRlIGRhZGVzIHF1ZSBlcyB2b2xlbiBhbmFsaXR6YXIvY29tcGFyYXIgKHBsYW5pZmljYWNpw7MgZGVscyBhbsOgbGlzaXMgYSBhcGxpY2FyKQoKPlRPRE86CkFncnVwYXIgcG9yIGNvbXVuaWRhZAoKIyMgQ29tcHJvdmFjacOzIGRlIGxhIG5vcm1hbGl0YXQgaSBob21vZ2VuZcOvdGF0IGRlIGxhIHZhcmnDoG5jaWEuCgpDb21lbsOnZW0gbWlyYW50IHNpIGxlcyB2YXJpYWJsZXMgcGVydGFueWVuIGEgdW5hIGRpc3RyaWJ1Y2nDsyBub3JtYWwuCgpgYGB7cn0KcF92YWxfc2FsX21pbiA8LSBzaGFwaXJvLnRlc3Qoc3Vic2V0KG9mZmVyc19zcCwgQ29tdW5pZGFkID09IGMoIk1BRFJJRCIpKSRTYWxhcmlvTWluKSRwLnZhbHVlCiNwX3ZhbF9zYWxfbWF4IDwtIHNoYXBpcm8udGVzdChvZmZlcnNfc3AkU2FsYXJpb01heCkkcC52YWx1ZQpzcHJpbnRmKCJQIHZhbHVlIHBhcmEgU2FsYXJpb01pbjogJWYiLCBwX3ZhbF9zYWxfbWluKQojc3ByaW50ZigiUCBWYWx1ZSBwYXJhIFNhbGFyaW9NYXg6ICVkIiwgcF92YWxfc2FsX21heCkKYGBgCgpgYGB7cn0KaGlzdChzdWJzZXQob2ZmZXJzX3NwLCBDb211bmlkYWQgPT0gYygiTUFEUklEIikpJFNhbGFyaW9NaW4pCmBgYAoKYGBge3J9Cmhpc3Qoc3Vic2V0KG9mZmVyc19zcCwgQ29tdW5pZGFkID09IGMoIkNBVEFMVcORQSIpKSRTYWxhcmlvTWluKQpgYGAKCiMjIEFwbGljYWNpw7MgZGUgcHJvdmVzIGVzdGFkw61zdGlxdWVzIHBlciBjb21wYXJhciBlbHMgZ3J1cHMgZGUgZGFkZXMuIEVuIGZ1bmNpw7MgZGUgbGVzIGRhZGVzIGRlIGwnb2JqZWN0aXUgZGUgbCdlc3R1ZGksIGFwbGljYXIgcHJvdmVzIGRlIGNvbnRyYXN0IGQnaGlww7J0ZXNpLCBjb3JyZWxhY2lvbnMsIHJlZ3Jlc3Npb25zLCBldGMuCgpgYGB7cn0KY29yX21hdHJpeCA8LSBjb3Iob2ZmZXJzX3NwJFNhbGFyaW9NaW4sIG9mZmVyc19zcCRTYWxhcmlvTWF4KQpyb3VuZChjb3JfbWF0cml4LCAyKQpgYGAKCkVuIGFxdWVzdCBwdW50LCBlbnMgYWRvbmVtIHF1ZSBoaSBoYSB1biB0aXB1cyBkZSByZWdpc3RyZXMgZW4gZWxzIHF1YWxzIHRlbmltIDAgYSBzYWxhcmkgbWluaW0gaSBtw6F4aW0sIGxvIHF1ZSB2b2wgZGlyIHF1ZSBhcXVlc3RlcyBvZmVydGVzIG5vIGhhbiBpbnRyb2R1aXQgdW4gdmFsb3IgcmVhbCBlbiBxdWFudCBhbHMgc2FsYXJpcywgbyBiw6kgc29uIG9mZXJ0ZXMgZGUgcHLDoGN0aXF1ZXMgbm8gcmVtdW5lcmFkZXMuIE5pbmd1bmEgZCdhcXVlc3RlcyBvcGNpb25zIGxlcyB2b2xlbSBjb250ZW1wbGFyIGVuIGVsIG5vc3RyZSBlc3R1ZGksIGFpeMOtIHF1ZSBjb20gdGVuaW0gZGFkZXMgc3VmaWNpZW50cywgcG9kZW0gcHJlc2NpbmRpciBkJ2FxdWVzdGVzLgoKYGBge3J9Cm9mZmVyc19zcCA8LSBzdWJzZXQob2ZmZXJzX3NwLCAhKFNhbGFyaW9NaW4gPT0gMCAmIFNhbGFyaW9NYXggPT0gMCkpCmBgYAoKPiBUT0RPOiBFbiBjb21wdGVzIGQndXRpbGl0emFyIEtOTiB1dGlsaXR6YXIgbGVzIG1pdGphbmVzIHBvYmxhY2lvbmFscyBwZXIgY2F0ZWdvcmlhCj4gVE9ETzogSGkgaGEgdmFsb3JzIGRlIHNhbGFyaSBNaW4gaSBNYXggcXVlIHMnaGFuIGQnaW50ZXJjYW52aWFyLgoKCiMgNS4gUmVwcmVzZW50YWNpw7MgZGVscyByZXN1bHRhdHMgYSBwYXJ0aXIgZGUgdGF1bGVzIGkgZ3LDoGZpcXVlcy4KCiMgNi4gUmVzb2x1Y2nDsyBkZWwgcHJvYmxlbWEuIEEgcGFydGlyIGRlbHMgcmVzdWx0YXRzIG9idGluZ3V0cywgcXVpbmVzIHPDs24gbGVzIGNvbmNsdXNpb25zPyBFbHMgcmVzdWx0YXRzIHBlcm1ldGVuIHJlc3BvbmRyZSBhbCBwcm9ibGVtYT8KCiMgNy4gQ29kaTogQ2FsIGFkanVudGFyIGVsIGNvZGkKCg==